home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 1 / The 640 Meg Shareware Studio CD-ROM Volume I (Data Express)(1992).ISO / driver / macpab1.dsk / MACPA1.ZIP / AUDIODD / SOURCE / DEMO.C < prev    next >
C/C++ Source or Header  |  1992-06-30  |  210KB  |  4,900 lines

  1. /**************************************************************************/
  2. /* (C)Copyright International Business Machines Corp. 1991, 1992.         */
  3. /*                                                                        */
  4. /* All Rights Reserved.                                                   */
  5. /*                                                                        */
  6. /* Refer to "LICENSE.DOC" for information regarding the use of this file. */
  7. /*                                                                        */
  8. /**************************************************************************/
  9. /*                                                                        */
  10. /* Title:       ACPA Demo                                                 */
  11. /*                                                                        */
  12. /* Created by:  Bridget Ritthaler                                         */
  13. /*                                                                        */
  14. /* Description: This is a demo program for the ACPA card. This program    */
  15. /*              supports recording MIDI data to a standard MIDI file      */
  16. /*              and waveform data to a RIFF - WAVE file. It also supports */
  17. /*              playing standard MIDI files and both waveform and MIDI    */
  18. /*              data RIFF files.                                          */
  19. /*                                                                        */
  20. /* Operating Systems: Both DOS and OS/2 are supported. They each require  */
  21. /*              seperate builds.                                          */
  22. /*                                                                        */
  23. /**************************************************************************/
  24. /*****************************************************************************/
  25. /*                        SYSTEM INCLUDES                                    */
  26. /*****************************************************************************/
  27. #if IS_OS2
  28. #define INCL_DOSSEMAPHORES
  29. #define INCL_DOSPROCESS
  30. #endif
  31.  
  32. #include "demodef.h"                   /* #define header file                */
  33. #include "demomsg.h"                   /* All displayed messages             */
  34.  
  35. #if IS_OS2
  36.  #include <os2.h>                      /* Use MS C 6.00A                     */
  37. #else
  38.  #include <dos.h>                      /* IBM C/2 or MS C                    */
  39. #endif
  40.  
  41. #include "audiodd.h"                   /* Audio Device Driver structures     */
  42.  
  43. #include <graph.h>                     /* Display routines in IBM C/2        */
  44.                                        /*  (Must use MS C 6.00A for OS/2)    */
  45.  
  46. #include <conio.h>
  47. #include <string.h>
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <fcntl.h>                     /* File I/O flags                     */
  51. #include <sys\types.h>                 /* File status/time types             */
  52. #include <sys\stat.h>                  /* File status flags/structs          */
  53. #include <io.h>                        /* File IO declarations               */
  54. #include <errno.h>                     /* File I/O error constants           */
  55. #include <malloc.h>                    /* _fmalloc() and _ffree()            */
  56.  
  57. unsigned long num_of_f8s = 0;
  58. /*****************************************************************************/
  59. /*                 RESIDENT FUNCTION DECLARATIONS                            */
  60. /*****************************************************************************/
  61. unsigned char nextbyte (int trk);
  62. void          freebuffs(unsigned int, unsigned int);
  63. int           read_kb  (char*,unsigned int);
  64. void          outmsg   (int type, int msg_num);
  65. void          outemsg  (int type, int msg_num);
  66. void          endemsg  (int type);
  67. void          restore  (short, long, struct rccoord);
  68. int           midi2seq (unsigned long);
  69. int           seq2midi (unsigned char*, int, unsigned long *);
  70. int           audrec   (void);
  71. int           audplay  (void);
  72. int           write_midi_headers(void);
  73. int           write_riff_headers(void);
  74. int           write_midi_lengths(void);
  75. int           write_riff_lengths(void);
  76. int           send_data(unsigned char *, unsigned long, int);
  77. void          update_count(void);
  78. void          buff_data(unsigned char);
  79. int           play_data(unsigned long, struct audio_init);
  80. void          dcwrite(char *data, int len, unsigned int num_buffers);
  81. void          change_settings(void);
  82. int           (far *direct_call)(int,char far *,int);
  83. #if IS_DOS
  84.  int          ioctl(void far *Data,unsigned char Function,int DevHandle);
  85.  int          dspload(char *name, int audstr);
  86. extern void   callback(void);
  87. #else
  88.  int          dspload(char *name, HFILE audstr);
  89. #endif
  90.  
  91. /*****************************************************************************/
  92. /*                VARIABLE DECLARATION/DEFINITIONS                           */
  93. /*****************************************************************************/
  94.  
  95. int chan_i;
  96. int file_type;
  97. int monitor=1;
  98. int cb_flag; /* flag for callback function to be included */
  99. int pos_flag; /* flag for display of position value to be included */
  100. int update_flag; /* flag for AUDIO_UPDATE processing */
  101. unsigned int update_index; /* index into update_array */
  102. char sem_name[] = {"\\sem\\demowait1.sem"};
  103. unsigned long delay;
  104. char wasur;
  105. unsigned int batch_time;
  106. struct update_array_s {
  107.    unsigned long length;       /* note - user may pass in >1 buff     */
  108.    char far *Virt;             /* User's virtual address              */
  109. } update_array[16];
  110.  
  111. struct track_info devinfo;
  112.  
  113. #if IS_DOS
  114.  union REGS dosregs;
  115. #else
  116.  unsigned short ActionTaken;
  117. #endif
  118.  
  119. struct devid dev_input;
  120. struct devid dev_output;
  121.  
  122. char            batch = FALSE;
  123. int             index;
  124. unsigned long   argint;
  125. char            *stopstring;
  126. char            iname[MAXSTRING];      /* MIDI file to be played             */
  127. char            filerate[MAXSTRING];   /* Type of file being played          */
  128. char            old_string_read[MAXSTRING]; /* last MIDI file played         */
  129. char            delta_time;            /* flag to see if delta_time was just */
  130.                                        /* written or if 0 time should be added*/
  131. char            status[9] = {"Stopped "};
  132. char            cur_balance_s[7] = {"Middle"};
  133. char            cur_volume_s[11] = {"---------*"};
  134. char            audioname[9] = "AUDIO1$";
  135.  
  136. unsigned char midi_buff[MIDI_BUFF_LEN];
  137. unsigned int  midi_buff_index;
  138.  
  139. unsigned char RIFF_header[8] = {'R','I','F','F','0','0','0','0'};
  140. unsigned char WAVE_header[4] = {'W','A','V','E'};
  141. unsigned char ibmw_header[4] = {'i','b','m','w'};
  142. unsigned char fmt_header[8]  = {'f','m','t',' ','0','0','0','0'};
  143. unsigned char data_header[8] = {'d','a','t','a','0','0','0','0'};
  144. unsigned char tempo_meda[7] = {0, 0xff, 0x51, 3, 0, 0, 0};
  145. unsigned char header[14] = {'M','T','h','d',0,0,0,6,0,0,0,1,0,0x78};
  146.        /*    chunk_type[4]       0-3     MThd ASCII characters               */
  147.        /*    length              4-7     length of header data               */
  148.        /*    format              8-9     overall organization of the file    */
  149.        /*                                note: only format = 0 supported     */
  150.        /*    ntrks               10-11   number of track chunks in the file  */
  151.        /*                                note: always 1 for format 0         */
  152.        /*    division            12-13   meaning of the delta-times          */
  153.        /*                                note: SMPTE time not supported      */
  154.  
  155. unsigned char   eot_meda[4] = {0, 0xff, 0x2F, 0};
  156. unsigned char   track[8] = {'M','T','r','k',0,0,0,0};
  157.        /*    chunk_type[4]       0-3     MTrk ASCII characters               */
  158.        /*    length              4-7     length of header data               */
  159. unsigned char timinit[10] = { 0xf0, 0, 0, 0x3a, 3, 1, 0x08, 3, 0, 0xf7 };
  160. unsigned char   timesysex[8] = { 0xf0, 0, 0, 0x3a, 1, 0, 0, 0xf7 };
  161. unsigned char   tempo_sysex[10] = { 0xf0,0,0,0x3a,3,2,0,0,0,0xf7 };
  162.  
  163. int  inhndl,                           /* File handle for input file         */
  164.      last_data_bytes,                  /* total number of bytes for the      */
  165.                                        /* running status                     */
  166.      data_bytes;                       /* number of data bytes that go with  */
  167.                                        /* current status                     */
  168.  
  169. #if IS_DOS
  170.  int  audhndl;                         /* Low level I/O file handle for      */
  171.  int  saudhndl;
  172. #else                                  /* AUDIO1 device                      */
  173.  HFILE audhndl;
  174.  HFILE saudhndl;
  175. #endif
  176.  
  177. int   started;                         /* current play/record status         */
  178. int   rc;                              /* return code from function calls    */
  179. int   x,y;                             /* loop counter for MODE determination*/
  180. unsigned int sy;
  181. int   user_esc;                        /* flag to determine when to exit     */
  182. int   eat;                             /* number of data bytes to eat        */
  183.  
  184. long  runtotal;               /* total # bytes played/recorded by DD*/
  185. long  old_runtotal;
  186. long  playtotal=0;            /* total # bytes played by the DD   */
  187. long  old_playtotal=0;
  188. long  cur_volume = 0x7fffffff;
  189. long  cur_balance = 0x3fffffff;
  190. long  cur_input = STEREO_LINE_INPUT;
  191.  
  192.  
  193. unsigned char   timinitr[10] = { 0xf0, 0, 0, 0x3a, 3, 1, 0x18, 3, 0, 0xf7 };
  194. unsigned char   *trkdata[128];         /* Up to 128 tracks                   */
  195. unsigned char   running_status;        /* last status byte                   */
  196.  
  197. unsigned int    remtracks;             /* # remaining tracks to do           */
  198.  
  199. unsigned long   delta[128];            /* # clocks to next event             */
  200. unsigned long   trklen[128];           /* Track remaining lengths            */
  201.          long   esc_count;             /* Count left in buffer when ESC hit  */
  202.                                        /* during a record                    */
  203. #if IS_OS2
  204. HSEM callback;
  205. unsigned long error_count=0;
  206. #endif
  207. unsigned long interrupt_count=0;
  208.  
  209. struct   audio_init init;              /* structure for audio initialization */
  210.  
  211. int      exit_ch=FALSE;
  212. int      channels;                     /* 1 = mono      2 = stereo           */
  213.  
  214. /* mode_table structure */
  215. struct mode_data {
  216.    short mode;                        /* mode #                              */
  217.    long  flags_mask;                  /* relevant flags                      */
  218.    long  flags;                       /* flag values                         */
  219.    short bps_low;                     /* bits_per_sample lower limit         */
  220.    short bps_high;                    /* bits_per_sample upper limit         */
  221.    long  srate_low;                   /* srate lower limit                   */
  222.    long  srate_high;                  /* srate upper limit                   */
  223.    short channels_low;                /* channels lower limit                */
  224.    short channels_high;               /* channels upper limit                */
  225.    long  bsize;                       /* block size                          */
  226.    short dont_care;                   /* bitmap of don't-care values         */
  227. };
  228. struct mode_data mode_table[NUM_MODES] = {
  229.    MIDI,0,0,8,8,0,0,0,0,1,FLAGS+BPS+SRATE+CHANNELS+BSIZE, //MIDI
  230.    ADPCM,FIXED,FIXED,16,16,11025,11025,1,1,576,BPS+BSIZE, //AVC VOICE
  231.    ADPCM,FIXED,FIXED,16,16,22050,22050,1,1,1128,BPS+BSIZE,//AVC MUSIC
  232.    ADPCM,FIXED,FIXED,16,16,22050,22050,2,2,2256,BPS+BSIZE,//AVC STEREO
  233.    ADPCM,FIXED,FIXED,16,16,44100,44100,1,1,1128,BPS+BSIZE,//AVC HIGH QUALITY
  234.    PCM,0x3e,0,8,8,8000,8000,1,2,0,BSIZE,                  //PCM 8 bit 8K
  235.    PCM,0x3e,0,8,8,11025,11025,1,2,0,BSIZE,                //PCM 8 bit 11K
  236.    PCM,0x3e,0,8,8,22050,22050,1,2,0,BSIZE,                //PCM 8 bit 22K
  237.    PCM,0x3e,0,8,8,44100,44100,1,2,0,BSIZE,                //PCM 8 bit 44K
  238.    PCM,0x3e,TWOS_COMPLEMENT,16,16,8000,8000,1,2,0,BSIZE,  //PCM 16 bit 8K
  239.    PCM,0x3e,TWOS_COMPLEMENT,16,16,11025,11025,1,2,0,BSIZE,//PCM 16 bit 11K
  240.    PCM,0x3e,TWOS_COMPLEMENT,16,16,22050,22050,1,2,0,BSIZE,//PCM 16 bit 22K
  241.    PCM,0x3e,TWOS_COMPLEMENT,16,16,44100,44100,1,2,0,BSIZE,//PCM 16 bit 44K
  242.    PCM,0x3e,0,8,8,0,44100,1,1,0,BSIZE+SRATE,              //Other 8 bit PCM
  243.    PCM,0x3e,0,16,16,0,44100,1,1,0,BSIZE+SRATE,            //Other 16 bit PCM
  244.    SOURCE_MIX,0,0,8,8,8000,8000,1,1,0,FLAGS+BPS+BSIZE+SRATE+CHANNELS,//Source Mix
  245.    MU_LAW,0x3e,0,8,8,8000,8000,1,2,0,BSIZE,               //Mu-Law 8 bit 8K
  246.    MU_LAW,0x3e,0,8,8,11025,11025,1,2,0,BSIZE,             //Mu-Law 8 bit 11K
  247.    MU_LAW,0x3e,0,8,8,22050,22050,1,2,0,BSIZE,             //Mu-Law 8 bit 22K
  248.    MU_LAW,0x3e,0,8,8,44100,44100,1,2,0,BSIZE,             //Mu-Law 8 bit 44K
  249.    A_LAW,0x3e,0,8,8,8000,8000,1,2,0,BSIZE,                //A-Law 8 bit 8K
  250.    A_LAW,0x3e,0,8,8,11025,11025,1,2,0,BSIZE,              //A-Law 8 bit 11K
  251.    A_LAW,0x3e,0,8,8,22050,22050,1,2,0,BSIZE,              //A-Law 8 bit 22K
  252.    A_LAW,0x3e,0,8,8,44100,44100,1,2,0,BSIZE,              //A-Law 8 bit 44K
  253.    CLAIM_HDWR,0,0,0,0,0,0,0,0,0,FLAGS+BPS+BSIZE+SRATE+CHANNELS,//Claim Hardware
  254.    CVSD,0x3e,0,0,0,0,0,1,1,0,BSIZE,                       // CVSD - 0
  255.    CVSD,0x3e,0,0,1,1,0,1,1,0,BSIZE,                       // CVSD - 1
  256.    CVSD,0x3e,0,0,2,2,0,1,1,0,BSIZE,                       // CVSD - 2
  257.    CVSD,0x3e,0,0,3,3,0,1,1,0,BSIZE,                       // CVSD - 3
  258.    CVSD,0x3e,0,0,4,4,0,1,1,0,BSIZE,                       // CVSD - 4
  259.    CVSD,0x3e,0,0,5,5,0,1,1,0,BSIZE,                       // CVSD - 5
  260.    PCM,0x3e,0,8,8,7875,7875,1,2,0,BSIZE+FLAGS,           /* 7875K 8b PCM   */
  261.    PCM,0x3e,0,8,8,31500,31500,1,2,0,BSIZE+FLAGS,         /* 31500k 8b PCM  */
  262.    PCM,0x3e,0,8,8,48000,48000,1,2,0,BSIZE+FLAGS,         /* 48000k 8b PCM  */
  263.    PCM,0x3e,0,16,16,7875,7875,1,2,0,BSIZE+FLAGS,         /* 7875K 8b PCM   */
  264.    PCM,0x3e,0,16,16,31500,31500,1,2,0,BSIZE+FLAGS,       /* 31500k 8b PCM  */
  265.    PCM,0x3e,0,16,16,48000,48000,1,2,0,BSIZE+FLAGS,       /* 48000k 8b PCM  */
  266.    MU_LAW,0x3e,0,8,8,7875,7875,1,2,0,BSIZE+FLAGS,        /* 7875k 8b Mu-Law*/
  267.    MU_LAW,0x3e,0,8,8,31500,31500,1,1,0,BSIZE+FLAGS,      /* 31500k 8b Mu-Law*/
  268.    MU_LAW,0x3e,0,8,8,48000,48000,1,1,0,BSIZE+FLAGS,      /* 48000k 8b Mu-Law*/
  269.    A_LAW,0x3e,0,8,8,7875,7875,1,2,0,BSIZE+FLAGS,         /* 7875k 8b A-Law */
  270.    A_LAW,0x3e,0,8,8,31500,31500,1,1,0,BSIZE+FLAGS,       /* 31500k 8b A-Law*/
  271.    A_LAW,0x3e,0,8,8,48000,48000,1,1,0,BSIZE+FLAGS        /* 48000k 8b A-Law*/
  272. };
  273.  
  274. int     mode = 0;                       /* MIDI by default                   */
  275. int     mode_i = 0;                     /* Index into mode_table             */
  276. char    mode_s[10];                     /* String to input mode from screen  */
  277. char    rate_s[8];                      /* String to type of mode from screen*/
  278. unsigned long blocksize=280;
  279.  
  280. unsigned int num_rbuffers_r = 1;
  281. struct iobuf far *rbuf;                      /* transmit buffer                   */
  282. char far *rbuffer;
  283. unsigned int rbuffer_len_p[1] = {RBUFFERSIZEP};
  284. unsigned int rbuffer_len_r[128] = {RBUFFERSIZER};
  285. unsigned long rlength = RBUFFERSIZER;
  286.  
  287. unsigned int num_xbuffers_p = 1;
  288. struct iobuf far *xbuf;                      /* transmit buffer                   */
  289. char far *xbuffer;
  290. unsigned int xbuffer_len_p[128] = {XBUFFERSIZEP};
  291. unsigned int xbuffer_len_r[1] = {XBUFFERSIZER};
  292. unsigned long xlength = XBUFFERSIZEP;
  293.  
  294. unsigned int update_segnum;
  295. unsigned int prv_segnum;
  296. unsigned int available_buffs;
  297. unsigned int rtn_segnum;
  298. unsigned long update_cnt;
  299. unsigned long update_size;
  300. unsigned char far *update_ptr;
  301.  
  302. unsigned int old_segnum;
  303. unsigned int new_segnum;
  304. char far *old_tail;
  305. char far *new_tail;
  306. char supress=0;
  307. char mastervol=0;
  308. char audiowait=0;
  309.  
  310. int source_input = DEFAULT_INPUT;
  311. int source_output = DEFAULT_OUTPUT;
  312. char source_input_s[2];
  313. char source_output_s[2];
  314.  
  315. int   function;                        /* 0 if playback demo                 */
  316. #if IS_OS2
  317. short priority;
  318.  
  319. PIDINFO PidInfo;
  320. #endif
  321.  
  322. int x;
  323. void main(argc,argv)
  324. int       argc;
  325. char    *argv[];
  326. {
  327. /*****************************************************************************/
  328. /*                   LOCAL VARIABLE DEFINITIONS                              */
  329. /*****************************************************************************/
  330. short oldfgd;                          /* original foreground color          */
  331.  
  332. int   okfile;                          /* flag for valid filename            */
  333.                                        /* 1 if record demo                   */
  334. int   x,ch;                            /* character holder                   */
  335. int   not_picked;                      /* flag for while loop                */
  336. int   not_picked_s;                    /* flag for while loop                */
  337. int   inputmsgnum;
  338.  
  339. long  oldbgd;                          /* original background color          */
  340. struct rccoord oldpos;                 /* original cursor position           */
  341.  
  342.    /**************************************************************************/
  343.    /* Start of Code                                                          */
  344.    /**************************************************************************/
  345.    /* Save original foreground, background, and text positions               */
  346.    oldfgd = _gettextcolor();
  347.    oldbgd = _getbkcolor();
  348.    oldpos = _gettextposition();
  349.  
  350.    /* Set background color and clear the screen                           */
  351.    _setbkcolor(BLUE);
  352.    _clearscreen(_GCLEARSCREEN);
  353.  
  354.    outmsg(TITLE,GENERAL);           /* Write out general welcome title    */
  355.    outmsg(COPYRIGHT,0);             /* Write Copyright msg to display     */
  356.  
  357.    cb_flag = 0; /* initialize for no callback */
  358.    delay = 0;   /* initialize for no delay    */
  359.    update_flag = 0;  /* initialize for no AUDIO_UPDATE */
  360.    /* Parse input parameters */
  361.    for(x=1; x<argc; x++){
  362.       strupr(argv[x]);
  363.       if(*argv[x]=='?'){
  364.          outmsg(CLHELP,HELPHELP);
  365.          return;
  366.       }else if(!strcmp(argv[x],"/B?")){
  367.          outmsg(CLHELP,BATCHHELP);
  368.          return;
  369.       } else if(!strcmp(argv[x],"/C")) {
  370. //       if ((++x >= argc) || (!(cb_flag = atoi(argv[x]) & 0x0F00))){
  371.          if ((++x >= argc) ||
  372.             (*argv[x]<'1') || (*argv[x]>'9')) {    /* callback number  */
  373.             outemsg(ERROR,CBINVALID);
  374.             cb_flag = 0;
  375.          } else {
  376.             sem_name[14] = *argv[x];   /* Copy number to our sem name */
  377.             if ((++x >= argc) || (!(cb_flag = atoi(argv[x]) & 0x1F00))){
  378.                cb_flag = 0;
  379.                outemsg(ERROR,CBINVALID);
  380.             }
  381.          } /* endif */
  382.       } /* endif */
  383.       if(!strcmp(argv[x],"/D")){
  384.          if (++x >= argc) {
  385.             outemsg(ERROR,DELAYINVALID);
  386.          } else {
  387.             delay = atoi(argv[x]);                      /* Save delay time */
  388.          } /* endif */
  389.       } /* endif */
  390.       if(!strcmp(argv[x],"/N")){
  391.          if ((++x >= argc) ||
  392.             (*argv[x]<'2') || (*argv[x]>'9')) {    /* AUDIOx$ number       */
  393.             outemsg(ERROR,NUMINVALID);
  394.          } else {
  395.             audioname[5] = *argv[x];   /* Copy number to our audio name */
  396.          } /* endif */
  397.       } /* endif */
  398.       if(!strcmp(argv[x],"/V")){
  399.          if (++x < argc) {
  400.             argint = strtoul(argv[x],&stopstring,10);
  401.             mastervol = 1;
  402.             devinfo.master_volume = (unsigned int)argint;
  403.          } /* endif */
  404.       } /* endif */
  405.       if(!strcmp(argv[x],"/M")){
  406.          if (++x < argc) {
  407.             monitor = atoi(argv[x]);
  408.          } /* endif */
  409.       } /* endif */
  410.       if(!strcmp(argv[x],"/I")){
  411.          not_picked_s = TRUE;
  412.          while (not_picked_s) {
  413.             outmsg(USERINPUT,INPMODE); /* what input should be used */
  414.             outmsg(HELP,INPUTLIST);
  415.             _setbkcolor(BLACK);         /* draw a box for the user to */
  416.                                         /* enter the input            */
  417.             _settextcolor(GRAY);
  418.             _settextposition(6,((short)(strlen(user_msg[INPMODE][1]))+5));
  419.             _outtext("  ");
  420.             _settextposition(6,((short)(strlen(user_msg[INPMODE][1]))+5));
  421.  
  422.             if (read_kb(source_input_s,2) == 0) {
  423.                source_input = atoi(source_input_s);
  424.                if ((source_input > 12) || (source_input < 0)) {
  425.                   outmsg(WARNING,INPINVALID);
  426.                } else {
  427.                   not_picked_s = FALSE;
  428.                } /* endif */
  429.             }
  430.          } /* end while (not_picked_s) */
  431.          outmsg(ERROR,CLEARSCRN);
  432.          outmsg(HELP,CLEARSCRN);
  433.       } /* endif */
  434.       if(!strcmp(argv[x],"/O")){
  435.          not_picked_s = TRUE;
  436.          while (not_picked_s) {
  437.             outmsg(USERINPUT,OUTMODE); /* what input should be used */
  438.             outmsg(HELP,OUTPUTLIST);
  439.             _setbkcolor(BLACK);         /* draw a box for the user to */
  440.                                         /* enter the input            */
  441.             _settextcolor(GRAY);
  442.             _settextposition(6,((short)(strlen(user_msg[OUTMODE][1]))+5));
  443.             _outtext("  ");
  444.             _settextposition(6,((short)(strlen(user_msg[OUTMODE][1]))+5));
  445.  
  446.             if (read_kb(source_output_s,2) == 0) {
  447.                source_output = atoi(source_output_s);
  448.                if ((source_output > 12) || (source_output < 0)) {
  449.                   outmsg(WARNING,OUTINVALID);
  450.                } else {
  451.                   not_picked_s = FALSE;
  452.                } /* endif */
  453.             }
  454.          } /* end while (not_picked_s) */
  455.          outmsg(ERROR,CLEARSCRN);
  456.          outmsg(HELP,CLEARSCRN);
  457.       } /* endif */
  458.       if(!strcmp(argv[x],"/S")){
  459.          supress = 1;
  460.       } /* endif */
  461.       if(!strcmp(argv[x],"/T")){
  462.          pos_flag = 1;
  463.       } /* endif */
  464.       if(!strcmp(argv[x],"/U")){
  465.          update_flag = 1;
  466.       } /* endif */
  467.       if(!strcmp(argv[x],"/W")){
  468.          audiowait = 1;
  469.       } /* endif */
  470.       if(!strcmp(argv[x],"/P")){
  471.          if (++x < argc) {
  472.             argint = strtoul(argv[x],&stopstring,10);
  473.             num_xbuffers_p = (unsigned int)argint;
  474.             xlength = 0;
  475.             for (sy=0; sy<num_xbuffers_p; sy++) {
  476.                if (++x < argc) {
  477.                   argint = strtoul(argv[x],&stopstring,10);
  478.                   if (argint > 65000) {
  479.                      outemsg(ERROR,SIZEINVALID);
  480.                      argint = 65000;
  481.                   } /* endif */
  482.                   xbuffer_len_p[sy] = (unsigned int)argint;
  483.                   xlength += argint;
  484.                } else {
  485.                   outemsg(ERROR,NOSIZE);
  486.                   num_xbuffers_p = sy;
  487.                } /* endif */
  488.             } /* endfor */
  489.          } else {
  490.             outemsg(ERROR,NONUM);
  491.          } /* endif */
  492.       } /* endif */
  493.       if(!strcmp(argv[x],"/R")){
  494.          if (++x < argc) {
  495.             argint = strtoul(argv[x],&stopstring,10);
  496.             num_rbuffers_r = (unsigned int)argint;
  497.             rlength = 0;
  498.             for (sy=0; sy<num_rbuffers_r; sy++) {
  499.                if (++x < argc) {
  500.                   argint = strtoul(argv[x],&stopstring,10);
  501.                   if (argint > 65000) {
  502.                      outemsg(ERROR,SIZEINVALID);
  503.                      argint = 65000;
  504.                   } /* endif */
  505.                   rbuffer_len_r[sy] = (unsigned int)argint;
  506.                   rlength += argint;
  507.                } else {
  508.                   outemsg(ERROR,NOSIZE);
  509.                   num_rbuffers_r = sy;
  510.                } /* endif */
  511.             } /* endfor */
  512.          } else {
  513.             outemsg(ERROR,NONUM);
  514.          } /* endif */
  515.       }
  516.       if(!strcmp(argv[x],"/B")){
  517.          batch = TRUE;
  518.          if (++x < argc) {
  519.             if(*argv[x]=='p' || *argv[x]=='P') {   /* Get operation        */
  520.                function = PLAY_DEMO;      /* Copy number to our audio name */
  521.                if (++x < argc) {
  522.                   strncpy(iname,argv[x],MAXSTRING); /* get filename to play */
  523.                } else {
  524.                   outemsg(ERROR,BATCHNUMP);
  525.                   return;
  526.                } /* endif */
  527.             } else if (*argv[x]=='r' || *argv[x]=='R') {
  528.                function = RCD_DEMO;
  529.                if (++x < argc) {
  530.                   strncpy(iname,argv[x],MAXSTRING); /* get filename to play */
  531.                   if (++x < argc) {
  532.                      index = atoi(argv[x]);
  533.                      if (index == 0) { /* MIDI */
  534.                         mode = MIDI;
  535.                         mode_i = 0;
  536.                         channels = 0;
  537.                         chan_i = NONE;
  538.                      } else if (index < 5) { /* ADPCM */
  539.                         mode = ADPCM;
  540.                         channels = 1;
  541.                         if (index == 1) {
  542.                            mode_i = AVC_VOICE;
  543.                         } else if (index == 2) {
  544.                            mode_i = AVC_MUSIC;
  545.                         } else if (index == 3) {
  546.                            mode_i = AVC_STEREO;
  547.                            channels = 2;
  548.                         } else {
  549.                            mode_i = AVC_HQ;
  550.                         } /* endif */
  551.                      } else if (index < 70) {  /* PCM-MU_LAW-A_LAW */
  552.                         if (index < 30) {
  553.                            mode = PCM;
  554.                            index -= 10;
  555.                         } else if (index < 50) {
  556.                            mode = MU_LAW;
  557.                            index -= 30;
  558.                         } else {
  559.                            mode = A_LAW;
  560.                            index -=50;
  561.                         } /* endif */
  562.                         if (index > 7) {
  563.                            channels = 2;
  564.                            index -= 8;
  565.                         } else {
  566.                            channels = 1;
  567.                         } /* endif */
  568.                         switch(index) {
  569.                            default:
  570.                               mode_i = PCM8k8b;
  571.                               break;
  572.                            case 1:
  573.                               mode_i = PCM8k16b;
  574.                               break;
  575.                            case 2:
  576.                               mode_i = PCM11k8b;
  577.                               break;
  578.                            case 3:
  579.                               mode_i = PCM11k16b;
  580.                               break;
  581.                            case 4:
  582.                               mode_i = PCM22k8b;
  583.                               break;
  584.                            case 5:
  585.                               mode_i = PCM22k16b;
  586.                               break;
  587.                            case 6:
  588.                               mode_i = PCM44k8b;
  589.                               break;
  590.                            case 7:
  591.                               mode_i = PCM44k16b;
  592.                               break;
  593.                         } /* end switch */
  594.                         if (mode == MU_LAW) {
  595.                            mode_i += 11;
  596.                         } else if (mode == A_LAW) {
  597.                            mode_i += 15;
  598.                         } /* endif */
  599.                      } else if (index < 130) {  /* M-Motion PCM-MU_LAW-A_LAW */
  600.                         if (index < 80) {
  601.                            mode = PCM;
  602.                            index -= 70;
  603.                         } else if (index < 100) {
  604.                            mode = MU_LAW;
  605.                            index -= 90;
  606.                         } else {
  607.                            mode = A_LAW;
  608.                            index -=110;
  609.                         } /* endif */
  610.                         if (index > 5) {
  611.                            channels = 2;
  612.                            index -= 6;
  613.                         } else {
  614.                            channels = 1;
  615.                         } /* endif */
  616.                         switch(index) {
  617.                            default:
  618.                               mode_i = PCM7k8b;
  619.                               break;
  620.                            case 1:
  621.                               mode_i = PCM7k16b;
  622.                               break;
  623.                            case 2:
  624.                               mode_i = PCM315k8b;
  625.                               break;
  626.                            case 3:
  627.                               mode_i = PCM315k16b;
  628.                               break;
  629.                            case 4:
  630.                               mode_i = PCM48k8b;
  631.                               break;
  632.                            case 5:
  633.                               mode_i = PCM48k16b;
  634.                               break;
  635.                         } /* end switch */
  636.                         if (mode == MU_LAW) {
  637.                            mode_i += 6;
  638.                         } else if (mode == A_LAW) {
  639.                            mode_i += 9;
  640.                         } /* endif */
  641.                      } else {
  642.                         outemsg(ERROR,BATCHFUNC);
  643.                         return;
  644.                      } /* endif */
  645.                      if (++x < argc) {
  646.                         batch_time = atoi(argv[x]) * 1000;
  647.                      } else {
  648.                         /* make largest number possible so never reached */
  649.                         batch_time = -1;
  650.                      } /* endif */
  651.                   } else {
  652.                      outemsg(ERROR,BATCHNUMP);
  653.                      return;
  654.                   } /* endif */
  655.                } else {
  656.                   outemsg(ERROR,BATCHNUMP);
  657.                   return;
  658.                } /* endif */
  659.             } else {
  660.                outemsg(ERROR,BATCHFUNC);
  661.                return;
  662.             } /* endif */
  663.          } else {
  664.             outemsg(ERROR,BATCHNUMP);
  665.             return;
  666.          } /* endif */
  667.       } /* endif */
  668.    }
  669.  
  670. #if IS_OS2
  671.    rc = DosGetPID(&PidInfo);
  672.    rc = DosGetPrty(0,&priority,PidInfo.pid);
  673.    if (cb_flag) {
  674. //    if (rc = DosCreateSem(1,&callback,"\\sem\\demowait.sem")) {
  675.       if (rc = DosCreateSem(1,&callback,sem_name)) {
  676.          outemsg(ERROR,CREATESEM);
  677.       }
  678.    } /* endif */
  679. #endif
  680.  
  681.    /* Allocate the iobufs */
  682.    if ((xbuf = (struct iobuf far *)_fmalloc((size_t)(sizeof(struct iobuf)+
  683.                        (num_xbuffers_p-1)*sizeof(struct addrs) ))) == NULL) {
  684.       outemsg(ERROR,MALLOCERR);     /* Write failed return code             */
  685.       restore(oldfgd,oldbgd,oldpos);          /* exit demo program     */
  686.       return;
  687.    }
  688.    if ((rbuf = (struct iobuf far *)_fmalloc((size_t)(sizeof(struct iobuf)+
  689.                        (num_rbuffers_r-1)*sizeof(struct addrs) ))) == NULL) {
  690.       outemsg(ERROR,MALLOCERR);     /* Write failed return code             */
  691.       _ffree(xbuf);
  692.       restore(oldfgd,oldbgd,oldpos);          /* exit demo program     */
  693.       return;
  694.    }
  695.  
  696. #if 0
  697.          #if IS_DOS
  698.           if((audhndl = open(audioname,O_BINARY | O_RDWR)) == -1){
  699.          #else
  700.           if(rc = DosOpen(audioname,&audhndl,&ActionTaken,0l,0,1,0x0012,0l)){
  701.          #endif
  702.             outmsg(HELP,BLANK);
  703.             outmsg(HELP,NODDINSTAL);         /* Display message on how to make sure*/
  704.                                              /* the device driver is installed     */
  705.             _settextposition(9,((short)(strlen(help_msg[NODDINSTAL][0]))+5));
  706.             printf("%s",audioname);
  707.             outmsg(STATUS,EXITDEMO);
  708.             exit_ch = getch();
  709.             restore(oldfgd,oldbgd,oldpos);          /* exit demo program     */
  710.             _ffree(xbuf);
  711.             _ffree(rbuf);
  712.             return;
  713.  
  714.          } /* endif rc = DosOpen */
  715. #endif
  716.  
  717.    do { /* until they want to exit */
  718.  
  719.  
  720.       user_esc = FALSE;
  721.       esc_count = 0;
  722.       runtotal = 0;
  723.       old_runtotal = 0;
  724.       playtotal = 0;
  725.       old_playtotal = 0;
  726.  
  727.  
  728.       okfile = FALSE;             /* init flag to check if 'p' or 'r' entered*/
  729.       user_esc = FALSE;           /* init exit flag to FALSE                 */
  730.  
  731.       while (!okfile && !batch) {
  732.  
  733.          outmsg(USERINPUT,PLAYRCD);    /* Ask the user whether he wants to   */
  734.                                        /* play a song or record one          */
  735.  
  736.          _settextposition(6,((short)(strlen(user_msg[PLAYRCD][1]))+5));
  737.          ch = getche();
  738.  
  739.          outmsg(HELP,CLEARSCRN);     /* Put out msg to user to tell them to  */
  740.  
  741.          if (ch == ESC) {
  742.  
  743.             exit_ch = TRUE;
  744.             restore(oldfgd,oldbgd,oldpos);          /* exit demo program     */
  745.             _ffree(xbuf);
  746.             _ffree(rbuf);
  747.             return;
  748.  
  749.          } /* endif ch = ESC */
  750.  
  751.          if ((ch == play_file) || (ch == PLAY_FILE)) {
  752.  
  753.             okfile = TRUE;
  754.             outmsg(TITLE,PLAYBACK);    /* Write Playback Title to display    */
  755.             inputmsgnum = PLAYFILE;
  756.             function = PLAY_DEMO;
  757.  
  758.          } else if ((ch == rcd_file) || (ch == RCD_FILE)) {
  759.  
  760.             okfile = TRUE;
  761.             outmsg(TITLE,RCD);         /* Write Record Title to display      */
  762.             inputmsgnum = RCDFILE;
  763.             function = RCD_DEMO;
  764.  
  765.          } else {
  766.  
  767.             outmsg(HELP,ENTERPR);    /* Put out msg to user to tell them to  */
  768.                                      /* enter a 'P' or 'R'                   */
  769.          } /* endif ch == R/P */
  770.  
  771.       } /* end while (!okfile) */
  772.  
  773.       okfile = FALSE;             /* init flag to check if valid fname given */
  774.  
  775.       while (!okfile) {
  776.  
  777.          if (!batch) {
  778.  
  779.             outmsg(USERINPUT,inputmsgnum);/* Write msg to get name of MIDI file */
  780.                                           /* to be played/created               */
  781.             _setbkcolor(BLACK);     /* draw a box for the user to enter fname  */
  782.             _settextcolor(GRAY);
  783.             _settextposition(7,30);
  784.             _outtext("                   ");
  785.             _settextposition(7,30);     /* put cursor at beginning of box       */
  786.  
  787.                                         /* read the file to play from the screen*/
  788.  
  789.          } /* endif */
  790.  
  791.          if (!batch) {
  792.             if (read_kb(iname,MAXSTRING) != 0) {
  793.                user_esc = TRUE;
  794.                okfile = TRUE;
  795.                ch = ' ';
  796.             }
  797.          } /* endif */
  798.          if (!user_esc) {
  799.             strupr(iname);
  800.             /* Check to see if a filename was entered                              */
  801.             if ((iname==NULL) || (iname=="?")) {
  802.  
  803.                if (function == PLAY_DEMO) {
  804.                   outmsg(HELP,NOFNAMEP);    /* put help info on screen for user */
  805.                } else { /* REC_DEMO */
  806.                   outmsg(HELP,NOFNAMER);    /* put help info on screen for user */
  807.                } /* endif function == PLAY_DEMO) */
  808.  
  809.             } else { /* if filename was entered, then try and open the file */
  810.  
  811.                if (function == PLAY_DEMO) {
  812.  
  813.                   /* Open input file                                                  */
  814.                   if ((inhndl=open(iname,O_BINARY | O_RDONLY)) == -1) {
  815.  
  816.                      outmsg(ERROR,FILNOTFNDP); /* Put error msg up saying can't */
  817.                                                /* open the filename entered     */
  818.                      _settextposition(10,30);  /* Write name of file to display */
  819.                      printf("%s",iname);
  820.                      outmsg(STATUS,EXITDEMO);  /* Tell user to press key        */
  821.  
  822.                   } else { /* file was found and opened successfully */
  823.  
  824.                      okfile = TRUE;
  825.  
  826.                      outmsg(YNQUEST,CLEARSCRN);
  827.                      outmsg(WARNING,CLEARSCRN);   /* Clear any warnings off     */
  828.  
  829.                   } /* endif */
  830.  
  831.                } else { /* RCD_DEMO */
  832.  
  833.                   not_picked = TRUE;
  834.  
  835.                   while (not_picked && !batch) {
  836.  
  837.                      outmsg(USERINPUT,PMODE);        /* See what mode to use       */
  838.                      outmsg(HELP,MODEDEFS);          /* List all the modes         */
  839.                      _setbkcolor(BLACK);             /* draw a box for the user to */
  840.                                                      /* enter the mode             */
  841.                      _settextcolor(GRAY);
  842.                      _settextposition(7,30);
  843.                      _outtext("                ");
  844.                      _settextposition(7,30);      /* put cur at beginning of box*/
  845.  
  846.                                                   /* read the mode              */
  847.                      not_picked = FALSE;
  848.  
  849.                      if (read_kb(mode_s,10) == 0) {
  850.                         ch = ' ';
  851.                         strupr(mode_s);
  852.                         if ((!(strncmp(mode_s,"PCM",3))) ||
  853.                             (!(strncmp(mode_s,"MU_LAW",6))) ||
  854.                             (!(strncmp(mode_s,"A_LAW",5)))) {
  855.                            if (!(strncmp(mode_s,"PCM",3))) mode = PCM;
  856.                            if (!(strncmp(mode_s,"MU_LAW",6))) mode = MU_LAW;
  857.                            if (!(strncmp(mode_s,"A_LAW",5))) mode = A_LAW;
  858.                            not_picked_s = TRUE;
  859.                            outmsg(WARNING,CLEARSCRN);
  860.                            while (not_picked_s) {
  861.  
  862.                               outmsg(USERINPUT,PCMMODES); /* what rate/bit count to use */
  863.                               if (mode == PCM) {
  864.                                  outmsg(HELP,MODEPCM);       /* List all the rates/counts  */
  865.                               } else { /* MU_LAW or A_LAW */
  866.                                  outmsg(HELP,MODELAW);       /* List all the rates/counts  */
  867.                               } /* endif */
  868.                               _setbkcolor(BLACK);         /* draw a box for the user to */
  869.                                                        /* enter the rate/count       */
  870.                               _settextcolor(GRAY);
  871.                               _settextposition(7,((short)(strlen(user_msg[PCMMODES][1]))+5));
  872.                               _outtext("                ");
  873.                               _settextposition(7,((short)(strlen(user_msg[PCMMODES][1]))+5));
  874.  
  875.                                                /* read the mode              */
  876.                               not_picked_s = FALSE;
  877.  
  878.                               if (read_kb(rate_s,8) == 0) {
  879.                                  ch = ' ';
  880.                                  strupr(rate_s);
  881.                                  if (!(strncmp(rate_s,"8K8S",4))) {
  882.                                          mode_i = PCM8k8b;
  883.                                          channels = 2;
  884.                                  } else if (!(strncmp(rate_s,"11K8S",5))) {
  885.                                          mode_i = PCM11k8b;
  886.                                          channels = 2;
  887.                                  } else if (!(strncmp(rate_s,"22K8S",5))) {
  888.                                          mode_i = PCM22k8b;
  889.                                          channels = 2;
  890.                                  } else if (!(strncmp(rate_s,"44K8S",5))) {
  891.                                          mode_i = PCM44k8b;
  892.                                          channels = 2;
  893.                                  } else if (!(strncmp(rate_s,"8K8",3))) {
  894.                                          mode_i = PCM8k8b;
  895.                                          channels = 1;
  896.                                  } else if (!(strncmp(rate_s,"11K8",4))) {
  897.                                          mode_i = PCM11k8b;
  898.                                          channels = 1;
  899.                                  } else if (!(strncmp(rate_s,"22K8",4))) {
  900.                                          mode_i = PCM22k8b;
  901.                                          channels = 1;
  902.                                  } else if (!(strncmp(rate_s,"44K8",4))) {
  903.                                          mode_i = PCM44k8b;
  904.                                          channels = 1;
  905.                                  } else if (mode == PCM) {
  906.                                     if (!(strncmp(rate_s,"8K16S",5))) {
  907.                                          mode_i = PCM8k16b;
  908.                                          channels = 2;
  909.                                     } else if (!(strncmp(rate_s,"11K16S",6))) {
  910.                                          mode_i = PCM11k16b;
  911.                                          channels = 2;
  912.                                     } else if (!(strncmp(rate_s,"22K16S",6))) {
  913.                                          mode_i = PCM22k16b;
  914.                                          channels = 2;
  915.                                     } else if (!(strncmp(rate_s,"44K16S",6))) {
  916.                                          mode_i = PCM44k16b;
  917.                                          channels = 2;
  918.                                     } else if (!(strncmp(rate_s,"8K16",4))) {
  919.                                          mode_i = PCM8k16b;
  920.                                          channels = 1;
  921.                                     } else if (!(strncmp(rate_s,"11K16",5))) {
  922.                                          mode_i = PCM11k16b;
  923.                                          channels = 1;
  924.                                     } else if (!(strncmp(rate_s,"22K16",5))) {
  925.                                          mode_i = PCM22k16b;
  926.                                          channels = 1;
  927.                                     } else if (!(strncmp(rate_s,"44K16",5))) {
  928.                                          mode_i = PCM44k16b;
  929.                                          channels = 1;
  930.                                     } else { /* not recognized/supported */
  931.                                          not_picked_s = TRUE;
  932.                                          outmsg(WARNING,NORATE);
  933.                                     } /* endif */
  934.                                  } else { /* not recognized/supported */
  935.                                       not_picked_s = TRUE;
  936.                                       outmsg(WARNING,NORATE);
  937.                                  } /* endif */
  938.                                  if (mode == MU_LAW) {
  939.                                     mode_i += 11;
  940.                                  } else if (mode == A_LAW) {
  941.                                     mode_i += 15;
  942.                                  } /* endif */
  943.                               } else {
  944.                                  ch = ESC;
  945.                               } /* endif ch != ESC */
  946.  
  947.                            } /* end while (not_picked_s) */
  948.  
  949.                         } else if (!(strncmp(mode_s,"ADPCM",5))) {
  950.  
  951.                            mode = ADPCM;
  952.                            not_picked_s = TRUE;
  953.                            outmsg(WARNING,CLEARSCRN);
  954.                            while (not_picked_s) {
  955.  
  956.                               outmsg(USERINPUT,AVCMODES); /* what rate/bit count to use */
  957.                               outmsg(HELP,MODEAVC);       /* List all the rates/counts  */
  958.                               _setbkcolor(BLACK);         /* draw a box for the user to */
  959.                                                        /* enter the rate/count       */
  960.                               _settextcolor(GRAY);
  961.                               _settextposition(7,30);
  962.                               _outtext("                ");
  963.                               _settextposition(7,30);      /* put cur at beginning of box*/
  964.  
  965.                               not_picked_s = FALSE;
  966.  
  967.                               if (read_kb(rate_s,8) == 0) {
  968.                                  ch = ' ';
  969.                                  strupr(rate_s);              /* convert mode to UPPERCASE  */
  970.  
  971.                                  if (!(strncmp(rate_s,"VOICE",5))) {
  972.                                          mode_i = AVC_VOICE;
  973.                                          channels = 1;
  974.                                  } else if (!(strncmp(rate_s,"MUSIC",5))) {
  975.                                          mode_i = AVC_MUSIC;
  976.                                          channels = 1;
  977.                                  } else if (!(strncmp(rate_s,"STEREO",6))) {
  978.                                          mode_i = AVC_STEREO;
  979.                                          channels = 2;
  980.                                  } else if (!(strncmp(rate_s,"HQ",2))) {
  981.                                          mode_i = AVC_HQ;
  982.                                          channels = 1;
  983.                                  } else { /* not recognized/supported */
  984.                                          not_picked_s = TRUE;
  985.                                          outemsg(WARNING,NOADPCM);
  986.                                  } /* end if rate_s */
  987.  
  988.                               } else {
  989.  
  990.                                  ch = ESC;
  991.  
  992.                               } /* endif */
  993.  
  994.                            } /* end while (not_picked_s) */
  995.  
  996.                         } else if (!(strncmp(mode_s,"CVSD",4))) {
  997.  
  998.                            mode = CVSD;
  999.                            not_picked_s = TRUE;
  1000.                            outmsg(WARNING,CLEARSCRN);
  1001.                            while (not_picked_s) {
  1002.  
  1003.                               outmsg(USERINPUT,CVSDMODES); /* what rate/bit count to use */
  1004.                               outmsg(HELP,MODECVSD);       /* List all the rates/counts  */
  1005.                               _setbkcolor(BLACK);         /* draw a box for the user to */
  1006.                                                        /* enter the rate/count       */
  1007.                               _settextcolor(GRAY);
  1008.                               _settextposition(7,30);
  1009.                               _outtext(" ");
  1010.                               _settextposition(7,30);      /* put cur at beginning of box*/
  1011.  
  1012.                               not_picked_s = FALSE;
  1013.  
  1014.                               if (read_kb(rate_s,1) == 0) {
  1015.                                  ch = ' ';
  1016.                                  strupr(rate_s);              /* convert mode to UPPERCASE  */
  1017.  
  1018.                                  if (!(strncmp(rate_s,"0",1))) {
  1019.                                          mode_i = CVSD_0;
  1020.                                  } else if (!(strncmp(rate_s,"1",1))) {
  1021.                                          mode_i = CVSD_1;
  1022.                                  } else if (!(strncmp(rate_s,"2",1))) {
  1023.                                          mode_i = CVSD_2;
  1024.                                  } else if (!(strncmp(rate_s,"3",1))) {
  1025.                                          mode_i = CVSD_3;
  1026.                                  } else if (!(strncmp(rate_s,"4",1))) {
  1027.                                          mode_i = CVSD_4;
  1028.                                  } else if (!(strncmp(rate_s,"5",1))) {
  1029.                                          mode_i = CVSD_5;
  1030.                                  } else { /* not recognized/supported */
  1031.                                          not_picked_s = TRUE;
  1032.                                          outemsg(WARNING,NOCVSD);
  1033.                                  } /* end if rate_s */
  1034.                                  channels = 1;
  1035.  
  1036.                               } else {
  1037.  
  1038.                                  ch = ESC;
  1039.  
  1040.                               } /* endif */
  1041.  
  1042.                            } /* end while (not_picked_s) */
  1043.  
  1044.                         } else if (!(strncmp(mode_s,"MIDI",4))) {
  1045.  
  1046.                            mode = MIDI;
  1047.                            mode_i = 0;
  1048.                            channels = 0;
  1049.                            chan_i = NONE;
  1050.                            outmsg(WARNING,CLEARSCRN);
  1051.  
  1052.                         } else { /* not recognized/supported */
  1053.  
  1054.                            not_picked = TRUE;
  1055.                            outmsg(WARNING,NOMODE);
  1056.  
  1057.                         } /* endif mode_s == */
  1058.  
  1059.                      } else {
  1060.  
  1061.                         ch = ESC;
  1062.  
  1063.                      } /* endif ch != ESC */
  1064.  
  1065.                   } /* endwhile not_picked */
  1066.  
  1067.                   outmsg(USERINPUT,CLEARSCRN);
  1068.                   outmsg(HELP,CLEARSCRN);
  1069.                   outmsg(WARNING,CLEARSCRN);
  1070.  
  1071.                   if (ch != ESC) {
  1072.  
  1073.                      /* Open output file                                              */
  1074.                      if(!(inhndl=open(iname,O_BINARY | O_WRONLY | O_CREAT
  1075.                                                          | O_TRUNC,S_IWRITE))==-1) {
  1076.                         outmsg(ERROR,FILNOTFNDR); /* Put error msg up saying can't */
  1077.                                                   /* open the filename entered     */
  1078.                         _settextposition(10,30);  /* Write name of file to display */
  1079.                         printf("%s",iname);
  1080.                         outmsg(STATUS,CONTINUE);  /* Tell user to press key        */
  1081.                         getch();
  1082.  
  1083.                      } else { /* file was opened successfully */
  1084.  
  1085.                         okfile = TRUE;
  1086.  
  1087.                      } /* endif */
  1088.  
  1089.                   } /* endif ch != ESC */
  1090.  
  1091.                } /* endif function == PLAY_DEMO */
  1092.  
  1093.             } /* endif */
  1094.  
  1095.          } /* endif */
  1096.  
  1097.       } /* endwhile */
  1098.  
  1099.  
  1100.       outmsg(STATUS,CLEARSCRN);                   /* clear status and error  */
  1101.       outmsg(ERROR,CLEARSCRN);                    /* messages                */
  1102.  
  1103.       if (!user_esc) {
  1104.  
  1105.          #if IS_DOS
  1106.           if((audhndl = open(audioname,O_BINARY | O_RDWR)) == -1){
  1107.          #else
  1108.           if(rc = DosOpen(audioname,&audhndl,&ActionTaken,0l,0,1,0x0012,0l)){
  1109.          #endif
  1110.             outmsg(HELP,BLANK);
  1111.             outmsg(HELP,NODDINSTAL);         /* Display message on how to make sure*/
  1112.                                              /* the device driver is installed     */
  1113.             _settextposition(9,((short)(strlen(help_msg[NODDINSTAL][0]))+5));
  1114.             printf("%s",audioname);
  1115.             outmsg(STATUS,EXITDEMO);
  1116.             exit_ch = getch();
  1117.             restore(oldfgd,oldbgd,oldpos);          /* exit demo program     */
  1118.             _ffree(xbuf);
  1119.             _ffree(rbuf);
  1120.             return;
  1121.  
  1122.          } /* endif rc = DosOpen */
  1123.  
  1124.          rbuffer = 0;
  1125.          xbuffer = 0;
  1126.          old_segnum = 0;
  1127.          available_buffs = 0;
  1128.          update_segnum = 0;
  1129.          update_cnt = 0;
  1130.          update_size = 0;
  1131.          rtn_segnum = 0;
  1132.          if (function == PLAY_DEMO) {
  1133.             if (update_flag && (num_xbuffers_p < 3)) {
  1134.                outemsg(ERROR,EUPDATEINVALID);
  1135.             } /* endif */
  1136.             rc = audplay();
  1137.          } else { /* RCD_DEMO */
  1138.             if (update_flag) {
  1139.                 outemsg(ERROR,EUPDATEWREC);
  1140.             } /* endif */
  1141.             rc = audrec();
  1142.          } /* endif function == PLAY_DEMO */
  1143.  
  1144.          close(inhndl);             /* close the MIDI standard file             */
  1145.          close(audhndl);
  1146.  
  1147.          if (!rc) freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  1148.  
  1149.          outmsg(WARNING,CLEARSCRN);
  1150.          outmsg(STATUS,EXITDEMO);   /* write message to exit program            */
  1151.          if (kbhit()) {
  1152.             ch = getch();         /* wait for a key to be pressed before exiting*/
  1153.          } /* endif */
  1154.  
  1155.       } else {
  1156.  
  1157.          outmsg(USERINPUT,CLEARSCRN);
  1158.  
  1159.       } /* endif */
  1160.  
  1161.  
  1162.    } while ((ch != ESC) && (!exit_ch) && !batch);
  1163.  
  1164. //  close(audhndl);
  1165.    restore(oldfgd,oldbgd,oldpos); /* restore original screen colors          */
  1166.      _ffree(xbuf);
  1167.      _ffree(rbuf);
  1168.  
  1169. } /* end main */
  1170.  
  1171.  
  1172. /*****************************************************************************/
  1173. /*                                                                           */
  1174. /*      FUNCTION NAME = restore                                              */
  1175. /*                                                                           */
  1176. /*      FUNCTION = restores the original display colors and cursor position  */
  1177. /*                                                                           */
  1178. /*      INPUT PARAMETERS = oldfgd - original foreground color                */
  1179. /*                         oldbgd - original background color                */
  1180. /*                         oldpos - original cursor position                 */
  1181. /*                                                                           */
  1182. /*      RETURN CODE = none                                                   */
  1183. /*                                                                           */
  1184. /*****************************************************************************/
  1185. void restore(short oldfgd, long oldbgd, struct rccoord oldpos)
  1186.  
  1187. {
  1188.  
  1189.    /* Restore original foreground and background and cursor positions        */
  1190.    _settextcolor(oldfgd);
  1191.    _setbkcolor(oldbgd);
  1192.    _clearscreen(_GCLEARSCREEN);
  1193.    _settextposition(oldpos.row, oldpos.col);
  1194.  
  1195. #if IS_OS2
  1196.       if (cb_flag) {
  1197.          if (rc = DosCloseSem(callback)) {
  1198.             outemsg(ERROR,CLOSESEM);
  1199.          }
  1200.       } /* endif */
  1201. #endif
  1202.  
  1203. } /* end restore() */
  1204.  
  1205. /*****************************************************************************/
  1206. /*                                                                           */
  1207. /*      FUNCTION NAME = audrec                                               */
  1208. /*                                                                           */
  1209. /*      FUNCTION = record input data to the output file                      */
  1210. /*                                                                           */
  1211. /*      INPUT PARAMETERS = none                                              */
  1212. /*                                                                           */
  1213. /*      RETURN CODE = 0 Successful                                           */
  1214. /*                    1 Failure                                              */
  1215. /*                                                                           */
  1216. /*****************************************************************************/
  1217.  
  1218. int audrec(void)
  1219. {
  1220.  
  1221. /*****************************************************************************/
  1222. /*                   LOCAL VARIABLE DEFINITIONS                              */
  1223. /*****************************************************************************/
  1224. int      ch;
  1225. int      x;
  1226. int      i;
  1227. char     wasor = 0;
  1228.  
  1229. unsigned long readsize;
  1230.  
  1231. struct   audio_control control;
  1232. struct   audio_change change;
  1233. struct   audio_hpi hpi;
  1234.  
  1235. char     wrap_it;
  1236.  
  1237. unsigned long   f8_count=0;        /* count of F8's broken off in last buffer*/
  1238.                                    /* passed to seq2midi routine             */
  1239.  
  1240.    /* Setup our own xbuffer */
  1241.    if ((xbuffer = (char far *)_fmalloc((size_t)XBUFFERSIZER))==NULL) {
  1242.       outemsg(ERROR,MALLOCERR);      /* Write failed return code             */
  1243.       close(audhndl);
  1244.       close(inhndl);
  1245.       freebuffs(1,0);
  1246.       return(1);
  1247.    }
  1248.    xbuf->size = XBUFFERSIZER;
  1249.    xbuf->num_buffers = 1;
  1250.    xbuf->buf[0].Virt = xbuffer;
  1251.    xbuf->buf[0].length = XBUFFERSIZER;
  1252.  
  1253.    xbuf->head = xbuffer;
  1254.    xbuf->tail = xbuffer;
  1255.    xbuf->count = 0;
  1256.    xbuf->runflags = 0;
  1257.  
  1258.  
  1259.    for (sy=0; sy<num_rbuffers_r; sy++) {
  1260.       if ((rbuffer = (char far *)_fmalloc((size_t)rbuffer_len_r[sy]))==NULL) {
  1261.          outemsg(ERROR,MALLOCERR);      /* Write failed return code             */
  1262.          close(audhndl);
  1263.          close(inhndl);
  1264.          freebuffs(1,sy);
  1265.          return(1);
  1266.       }
  1267.       rbuf->buf[sy].Virt = rbuffer;
  1268.       rbuf->buf[sy].length = rbuffer_len_r[sy];
  1269.    } /* endfor */
  1270.  
  1271.    rbuf->size = rlength;
  1272.  
  1273.    rbuf->num_buffers = num_rbuffers_r;
  1274.  
  1275.    rbuf->head = rbuf->buf[0].Virt;
  1276.    rbuf->tail = rbuf->buf[0].Virt;
  1277.    rbuf->count = 0;
  1278.    rbuf->runflags = cb_flag;
  1279.    rbuf->position = 0;
  1280.  
  1281.    hpi.cb = NULL;
  1282.    hpi.newxbuf = xbuf;
  1283.    hpi.newrbuf = rbuf;
  1284.    hpi.flags = 0;
  1285.    #if IS_DOS
  1286.     if(rc = ioctl(&hpi,AUDIO_HPI,audhndl)){
  1287.    #else
  1288.     if(rc = DosDevIOCtl(&hpi, NULL, 0x40+AUDIO_HPI, 0x80, audhndl)) {
  1289.    #endif
  1290.       outmsg(ERROR,HPIIOCTL);      /* Write failed return code             */
  1291.       _settextposition(11,30);
  1292.       printf("%i",rc);
  1293.       endemsg(ERROR);
  1294.       close(audhndl);
  1295.       close(inhndl);
  1296.       freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  1297.       return(1);
  1298.    }
  1299.    #if IS_DOS
  1300.     direct_call = hpi.ep;
  1301.    #endif
  1302.  
  1303.  
  1304.    /**************************************************************************/
  1305.    /* Issue INIT IOCtl                                                       */
  1306.    /**************************************************************************/
  1307.    init.mode = mode;
  1308.    init.flags = mode_table[mode_i].flags;
  1309.    init.srate = mode_table[mode_i].srate_low;
  1310.    init.bits_per_sample = mode_table[mode_i].bps_low;
  1311.    init.bsize = mode_table[mode_i].bsize;
  1312.    init.channels = channels;
  1313.    if (channels == 1) {
  1314.       chan_i = MONO;
  1315.    } else {
  1316.       chan_i = STEREO;
  1317.    } /* endif */
  1318.    init.operation = RECORD;
  1319.    init.rc = 0;
  1320.    init.reserved = NULL;
  1321.    init.version_level = CURRENT_VERSION;
  1322.    #if IS_DOS
  1323.    if(direct_call == NULL){
  1324.       rc = ioctl(&init,AUDIO_INIT,audhndl);
  1325.    }else{
  1326.       rc = (*direct_call)(EP_INIT,(char far *)&init,23);
  1327.    }
  1328.     if (rc) {
  1329.    #else
  1330.     if(rc = DosDevIOCtl(&init, NULL, 0x40+AUDIO_INIT, 0x80, audhndl)) {
  1331.    #endif
  1332.       outmsg(ERROR,EINITIOCTL);
  1333.       _settextposition(11,30);
  1334.       printf("%i",rc);
  1335.       endemsg(ERROR);
  1336.       close(audhndl);
  1337.       close(inhndl);
  1338.       freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  1339.       return(1);
  1340.     }
  1341.  
  1342.    if (init.flags & BESTFIT_PROVIDED) {
  1343.       mode = init.mode;
  1344.       channels = init.channels;
  1345.       outemsg(WARNING,BESTFIT);
  1346.    }
  1347.  
  1348.   /***************************************************************************/
  1349.   /* Load code module                                                        */
  1350.   /***************************************************************************/
  1351.    if (init.flags & LOAD_CODE) {     /* Load DSP code module                 */
  1352.       if (rc = dspload(&init.loadpath[0], audhndl)) {
  1353.          outmsg(ERROR,EDSPLOAD);     /* Write failed return code             */
  1354.          _settextposition(11,30);
  1355.          printf("%i",rc);
  1356.          endemsg(ERROR);
  1357.          close(audhndl);
  1358.          close(inhndl);
  1359.          freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  1360.          return(1);
  1361.       }
  1362.    } /* endif LOAD_CODE */
  1363.  
  1364.    if (init.rc != 0) {
  1365.  
  1366.       outmsg(ERROR,INITFAILED);      /* Write failed return code             */
  1367.       _settextposition(11,30);
  1368.       printf("%i",init.rc);
  1369.       endemsg(ERROR);
  1370.  
  1371.    } /* endif (rc != 0 ) */
  1372.  
  1373.    /* Issue CHANGE IOCtl */
  1374.    control.position = 0;                     /* Do it now                  */
  1375.    control.ioctl_request = AUDIO_CHANGE;     /* Change configuration       */
  1376.    control.return_code = 0;                  /* zero out return code field */
  1377.    control.request_info = &change;           /* Request data = change struct*/
  1378.    change.input_list[0].devtype = source_input;
  1379.    change.input_list[0].devnum  = DEVICE_1;
  1380.    change.output_list[0].devtype = source_output;
  1381.    change.output_list[0].devnum  = DEVICE_1;
  1382.    change.input_list[1].devtype = NULL_INPUT;
  1383.    change.input_list[1].devnum  = DEVICE_1;
  1384.    change.output_list[1].devtype = NULL_OUTPUT;
  1385.    change.output_list[1].devnum  = DEVICE_1;
  1386.    change.input = INPUTS_LISTED;
  1387.    change.output = OUTPUTS_LISTED;           /* Output select              */
  1388.    change.monitor = monitor;                 /* Monitor                    */
  1389.    change.volume = 0x7fffffff;               /* Volume set to maximum      */
  1390.    change.volume_delay = delay;              /* Set volume now             */
  1391.    change.balance = 0x3fffffff;              /* Balance set to mid-point   */
  1392.    change.balance_delay = delay;             /* Set balance now            */
  1393.    change.treble = 0x3fffffff;               /* Mid point                  */
  1394.    change.bass = 0x3fffffff;                 /* Mid point                  */
  1395.    change.pitch = 0;                         /*                            */
  1396.    if (mastervol) {
  1397.    change.dev_info = &devinfo;               /* Device dependent data      */
  1398.    } else {
  1399.    change.dev_info = NULL;                   /* No device dependent data   */
  1400.    }
  1401.    change.input_gain = 0;                    /* No input gain              */
  1402.    change.mode_info = NULL;                  /* No mode dependent data     */
  1403.    #if IS_DOS
  1404.     if(direct_call == NULL){
  1405.       rc = ioctl(&control,AUDIO_CONTROL,audhndl);
  1406.     }else{
  1407.       rc = (*direct_call)(EP_CONTROL,(char far *)&control,23);
  1408.     }
  1409.     /*************************************************************************/
  1410.     /* Issue IOCTL set device parameters to force BINARY mode (otherwise an  */
  1411.     /* 0x1a read will cause DOS to assume EOF) You might need to uncomment   */
  1412.     /* this if you want to build a DOS only version.                         */
  1413.     /*************************************************************************/
  1414.  
  1415.     dosregs.x.ax = 0x4401;
  1416.     dosregs.x.bx = audhndl;
  1417.     dosregs.x.dx = 0x00a0;
  1418.     intdos(&dosregs, &dosregs);
  1419.  
  1420.     if (rc) {
  1421.    #else
  1422.     if(rc = DosDevIOCtl(&control, NULL, 0x40+AUDIO_CONTROL, 0x80, audhndl)) {
  1423.    #endif
  1424.       outmsg(ERROR,ECHNGIOCTL);
  1425.       _settextposition(11,30);
  1426.       printf("%i",rc);
  1427.       endemsg(ERROR);
  1428.       close(audhndl);
  1429.       close(inhndl);
  1430.       freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  1431.       return(1);
  1432.     }
  1433.    /**************************************************************************/
  1434.  
  1435.    if (init.mode == MIDI) {
  1436.       if (write_midi_headers()){
  1437.          freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  1438.          return(1);
  1439.       }
  1440.    } else { /* RIFF mode */
  1441.       rc = write_riff_headers();
  1442.    } /* endif MIDI mode */
  1443.  
  1444.    outmsg(HELP,BLANK);
  1445.    outmsg(HELP,RECORD1);
  1446.    _settextposition(10,((short)(strlen(help_msg[RECORD1][1]))+5));
  1447.    printf("%s - %s %s",iname,file_type_msg[mode_i],mono_stereo_msg[chan_i]);
  1448.    _settextposition(11,((short)(strlen(help_msg[RECORD1][2]))+5));
  1449.    printf("%s",audioname);
  1450.    if (pos_flag) {
  1451.       _settextposition(12,5);
  1452.       _setbkcolor(AQUA);       /* Set background color            */
  1453.       _settextcolor(BLACK);    /* Set foreground/text color       */
  1454.       _outtext(extra_msg[POSITION]);
  1455.    } /* endif */
  1456.    if (cb_flag) {
  1457.       _settextposition(17,5);
  1458.       _setbkcolor(AQUA);       /* Set background color            */
  1459.       _settextcolor(BLACK);    /* Set foreground/text color       */
  1460.       _outtext(extra_msg[CBCOUNT]);
  1461.    } /* endif */
  1462.    outmsg(STATUS,STARTSTOP);
  1463.    started = 0;
  1464.    x = 0;
  1465.  
  1466.    running_status = 0;                     /* init to no running status      */
  1467.    last_data_bytes = 0;
  1468.    data_bytes = 0;                         /* init number of data bytes      */
  1469.                                            /* expected to none               */
  1470.    delta_time = FALSE;
  1471.    old_segnum = 0;
  1472.  
  1473.    do {
  1474.  
  1475.       /***********************************************************************/
  1476.       /* See how much data is available from the MIDI queue                  */
  1477.       /***********************************************************************/
  1478.       if (user_esc) {
  1479.          readsize = esc_count;
  1480.       } else {
  1481.          readsize = rbuf->count;
  1482.       } /* endif */
  1483.       if(readsize > 0x7ffe) readsize = 0x7ffe;     /* Limit to int range */
  1484.  
  1485.       /* Don't allow write to wrap around the buffer     */
  1486.  
  1487.       if(readsize >= (unsigned long)((rbuf->buf[rbuf->tail_segnum].Virt-rbuf->tail)
  1488.                     +rbuf->buf[rbuf->tail_segnum].length)){
  1489.          readsize = (unsigned long)((rbuf->buf[rbuf->tail_segnum].Virt-rbuf->tail)
  1490.                     +rbuf->buf[rbuf->tail_segnum].length);
  1491.          wrap_it = TRUE;
  1492.       } else {
  1493.          wrap_it = FALSE;
  1494.       }
  1495.  
  1496.  
  1497.       if (readsize > 0) {
  1498.  
  1499.          if (init.mode == MIDI) {                 /* MIDI data to record?    */
  1500.  
  1501.             if (readsize > 512) readsize = 512;
  1502.  
  1503.             runtotal += readsize;
  1504.  
  1505.  
  1506.             /********************************************************************/
  1507.             /* Convert data to MIDI standard format and write to file           */
  1508.             /********************************************************************/
  1509.  
  1510.             i = seq2midi(rbuf->tail,(int)readsize,&f8_count);
  1511.  
  1512.          } else { /* RIFF file being created */
  1513.  
  1514.             runtotal += readsize;
  1515.  
  1516.             /* Write out the buffer */
  1517.             i = write(inhndl,(char *)rbuf->tail,(unsigned)readsize);
  1518.             if (i != (int)readsize) {
  1519.                outmsg(ERROR,DISKFULL);
  1520.                _settextposition(10,30);
  1521.                printf("%s", iname);
  1522.                endemsg(ERROR);
  1523.                freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  1524.                return (1);
  1525.             } /* if ndata = -1 */
  1526.  
  1527.          } /* endif */
  1528.  
  1529.          if (user_esc) {
  1530.             esc_count -= i;
  1531.          } /* endif */
  1532.  
  1533.          if (wrap_it) {
  1534.             if (++rbuf->tail_segnum >= num_rbuffers_r) {
  1535.                rbuf->tail_segnum = 0;
  1536.             } /* endif */
  1537.             rbuf->tail = rbuf->buf[rbuf->tail_segnum].Virt;
  1538.          } else {
  1539.             rbuf->tail += i;
  1540.          } /* endif */
  1541.          rbuf->runflags |= IOBUF_LOCK;
  1542.          rbuf->count -= i;
  1543.          rbuf->runflags &= ~IOBUF_LOCK;
  1544.  
  1545.       } /* endif readsize > 0 */
  1546.  
  1547.       if (batch) {
  1548.          if (rbuf->position) {
  1549.             if (rbuf->position >= batch_time) {
  1550.                rbuf->runflags &= ~STARTED;
  1551.                esc_count = rbuf->count;
  1552.                user_esc = TRUE;
  1553.                started = 1;
  1554.             } /* endif */
  1555.          } else {
  1556.             rbuf->runflags |= STARTED;
  1557.             started = 1;
  1558.             strcpy(status,"Running ");
  1559.          } /* endif */
  1560.       } /* endif */
  1561.  
  1562.       /**************************/
  1563.       /* Process keyboard input */
  1564.       /**************************/
  1565.       if (kbhit()) {
  1566.  
  1567.          ch=getch();
  1568.  
  1569.          switch(ch){
  1570.  
  1571.             case ' ':
  1572.                if (!started) {                 /* If not started, issue START*/
  1573.                   started = 1;
  1574.                   rbuf->runflags |= STARTED;
  1575.                   strcpy(status,"Running ");
  1576.                } else if (started==1) {        /* If running, issue PAUSE    */
  1577.                   started=2;
  1578.                   rbuf->runflags |= PAUSED;
  1579.                   strcpy(status,"Paused  ");
  1580.                } else {                        /* if paused, issue RESUME    */
  1581.                   started = 1;
  1582.                   rbuf->runflags &= ~PAUSED;
  1583.                   strcpy(status,"Resumed ");
  1584.                }
  1585.                break;
  1586.  
  1587.             case 'L':
  1588.             case 'l':
  1589.                cur_input = LEFT_LINE_INPUT;
  1590.                change_settings();
  1591.                break;
  1592.  
  1593.             case 'R':
  1594.             case 'r':
  1595.                cur_input = RIGHT_LINE_INPUT;
  1596.                change_settings();
  1597.                break;
  1598.  
  1599.             case 'S':
  1600.             case 's':
  1601.                cur_input = STEREO_LINE_INPUT;
  1602.                change_settings();
  1603.                break;
  1604.  
  1605.             case 'M':
  1606.             case 'm':
  1607.                cur_input = MIC_INPUT;
  1608.                change_settings();
  1609.                break;
  1610.  
  1611.             case '0':
  1612.                monitor = 0;
  1613.                change_settings();
  1614.                break;
  1615.  
  1616.             case '1':
  1617.                monitor = 1;
  1618.                change_settings();
  1619.                break;
  1620.  
  1621.             case '3':
  1622.                monitor = 3;
  1623.                change_settings();
  1624.                break;
  1625.  
  1626.             case 'B':
  1627.             case 'b':
  1628.                cur_input = BOOSTED_MIC_INPUT;
  1629.                change_settings();
  1630.                break;
  1631.  
  1632.           case ESC:                          /* Esc = quit                 */
  1633.                rbuf->runflags &= ~STARTED;
  1634.                esc_count = rbuf->count;
  1635.                user_esc = TRUE;
  1636.                started = 1;
  1637.                break;
  1638.  
  1639.             default:
  1640.                break;
  1641.  
  1642.          } /* end switch */
  1643.  
  1644.          _settextposition(13,((short)(strlen(help_msg[RECORD1][4]))+5));
  1645.          printf("%s",status);
  1646.  
  1647.       } /* endif */
  1648.  
  1649.       if (rbuf->runflags & IOB_OVERRUN) {
  1650.          wasor = 1;
  1651.          outmsg(WARNING,OVERRUN);
  1652.          rbuf->runflags &= ~IOB_OVERRUN;
  1653.       } else if (wasor) {
  1654.          wasor = 0;
  1655.          outmsg(WARNING,CLEARSCRN);
  1656.       } /* endif */
  1657.  
  1658.       if (!supress) {
  1659.          if (old_runtotal != runtotal) {
  1660.             old_runtotal = runtotal;
  1661.             _settextposition(15,((short)(strlen(help_msg[RECORD1][6]))+5));
  1662.             printf("%6.6ld",runtotal);
  1663.             if (pos_flag) {
  1664.                _settextposition(12,((short)(strlen(extra_msg[POSITION]))+5));
  1665.                printf("%6.6ld",rbuf->position);
  1666.             } /* endif */
  1667.             if (cb_flag) {
  1668.                _settextposition(17,((short)(strlen(extra_msg[CBCOUNT]))+5));
  1669.                printf("%6.6ld",interrupt_count);
  1670.             } /* endif */
  1671.          } /* endif */
  1672.       } /* endif */
  1673.  
  1674.    } while ((user_esc == FALSE) ||
  1675.            ((user_esc == TRUE) && (esc_count > 0)));
  1676.  
  1677.    rbuf->runflags |= IOBUF_LOCK;
  1678.    rbuf->count = 0;
  1679.    rbuf->tail_segnum = 0;
  1680.    rbuf->head = rbuf->tail = rbuf->buf[0].Virt;
  1681.    rbuf->runflags &= ~IOBUF_LOCK;
  1682.  
  1683.  
  1684.    if (init.mode == MIDI) { /* MIDI file being created ? */
  1685.       rc = write_midi_lengths();
  1686.    } else { /* RIFF format needed */
  1687.       rc = write_riff_lengths();
  1688.    } /* endif MIDI file being created */
  1689.  
  1690.    outmsg(HELP,BLANK);
  1691.  
  1692.    return (0);
  1693.  
  1694. } /* end audrec */
  1695.  
  1696.  
  1697. /*****************************************************************************/
  1698. /*                                                                           */
  1699. /*      FUNCTION NAME = write_riff_headers                                   */
  1700. /*                                                                           */
  1701. /*      FUNCTION = write RIFF chunk headers                                  */
  1702. /*                                                                           */
  1703. /*      INPUT PARAMETERS = none                                              */
  1704. /*                                                                           */
  1705. /*      RETURN CODE = 0 Successful                                           */
  1706. /*                    1 Failure                                              */
  1707. /*                                                                           */
  1708. /*****************************************************************************/
  1709.  
  1710. int write_riff_headers(void)             /* Begin Function                   */
  1711. {
  1712.  
  1713. /*****************************************************************************/
  1714. /*                   LOCAL VARIABLE DEFINITIONS                              */
  1715. /*****************************************************************************/
  1716. unsigned int  ndata;
  1717.  
  1718. struct waveformat_s {
  1719.    unsigned int  formattag;            /* format category                    */
  1720.    unsigned int  nchannels;            /* number of channels                 */
  1721.    unsigned long nsamplespersec;       /* sampling rate                      */
  1722.    unsigned long navgbytespersec;      /* for buffering                      */
  1723.    unsigned int  nblockalign;          /* block alignment                    */
  1724.    unsigned int  nbitspersample;       /* sample size                        */
  1725. } waveformat;
  1726.  
  1727.    /* Write out 'RIFF' and dummy length                                      */
  1728.    if ((ndata = (unsigned)write(inhndl,(char *)RIFF_header,8)) == 8) {
  1729.       /* Write out 'WAVE' or 'ibmw'                                          */
  1730.          if (mode == CVSD) {
  1731.             ndata = (unsigned)write(inhndl,(char *)ibmw_header,4);
  1732.          } else {
  1733.             ndata = (unsigned)write(inhndl,(char *)WAVE_header,4);
  1734.          } /* endif */
  1735.       if (ndata == 4) {
  1736.          /* Write out 'fmt ' and dummy length                                */
  1737.          if ((ndata = (unsigned)write(inhndl,(char *)fmt_header,8)) == 8) {
  1738.             switch (mode) {
  1739.                case PCM:
  1740.                     waveformat.formattag = 1;                          /* format category */
  1741.                     break;
  1742.                case MU_LAW:
  1743.                     waveformat.formattag = 0x0101;
  1744.                     break;
  1745.                case A_LAW:
  1746.                     waveformat.formattag = 0x0102;
  1747.                     break;
  1748.                case ADPCM:
  1749.                     waveformat.formattag = 0x0103;
  1750.                     break;
  1751.                case CVSD:
  1752.                     waveformat.formattag = 5;
  1753.                     break;
  1754.             } /* end switch */
  1755.  
  1756.             waveformat.nchannels = channels;                   /* number of channels*/
  1757.             waveformat.nsamplespersec = init.srate;            /* sampling rate   */
  1758.                                                                /* sample size*/
  1759.             waveformat.nbitspersample = (int)init.bits_per_sample;
  1760.             waveformat.nblockalign = waveformat.nchannels      /* block alignment */
  1761.                                            * (waveformat.nbitspersample / 8);
  1762.                                                                /* avg bytes/sec   */
  1763.             waveformat.navgbytespersec = waveformat.nchannels * waveformat.nsamplespersec
  1764.                                              * (waveformat.nbitspersample / 8);
  1765.             /* Write out wave format structure                               */
  1766.             if ((ndata = (unsigned)write(inhndl,(char *)&waveformat,16)) == 16) {
  1767.                /* Write out 'data' and dummy length                                      */
  1768.                if ((ndata = (unsigned)write(inhndl,(char *)data_header,8)) == 8) {
  1769.                   return(0);                         /* return successfully  */
  1770.                } /* endif */
  1771.             } /* endif */
  1772.          } /* endif */
  1773.       } /* endif */
  1774.    } /* endif */
  1775.  
  1776.    /* if got to here then we failed somewhere - report error                 */
  1777.    outmsg(HELP,CLEARSCRN);
  1778.    outmsg(ERROR,DISKFULL);
  1779.    _settextposition(10,30);
  1780.    printf("%s", iname);
  1781.    endemsg(ERROR);
  1782.    return (1);
  1783.  
  1784. } /* end write_riff_headers() */
  1785.  
  1786. /*****************************************************************************/
  1787. /*                                                                           */
  1788. /*      FUNCTION NAME = write_midi_headers                                   */
  1789. /*                                                                           */
  1790. /*      FUNCTION = write HEADER Chunk and beginning of TRACK chunk to file   */
  1791. /*                                                                           */
  1792. /*      INPUT PARAMETERS = none                                              */
  1793. /*                                                                           */
  1794. /*      RETURN CODE = 0 Successful                                           */
  1795. /*                    1 Failure                                              */
  1796. /*                                                                           */
  1797. /*****************************************************************************/
  1798.  
  1799. int write_midi_headers(void)             /* Begin Function                   */
  1800. {
  1801.  
  1802. /*****************************************************************************/
  1803. /*                   LOCAL VARIABLE DEFINITIONS                              */
  1804. /*****************************************************************************/
  1805. char          tpqn_s[3];           /* string value of tpqn                   */
  1806. int           ch;
  1807. int           tpqn;                /* int value for tpqn                     */
  1808. int           tpqn_not_valid;
  1809. int           ndata;
  1810. unsigned long tttttt;              /* tempo - beats per minute               */
  1811.  
  1812.    tpqn_not_valid = TRUE;
  1813.  
  1814.    while (tpqn_not_valid) {
  1815.       /* Ask the user how many ticks per quarter - default 120               */
  1816.       outmsg(USERINPUT,TPQN);       /* Write msg to get the tpqn to use      */
  1817.  
  1818.       _setbkcolor(BLACK);           /* draw a box for the user to enter tpqn */
  1819.       _settextcolor(GRAY);
  1820.       _settextposition(7,30);
  1821.       _outtext("        ");
  1822.       _settextposition(7,30);        /* put cursor at beginning of box       */
  1823.  
  1824.       _settextposition(7,30);        /* put cursor at beginning of box       */
  1825.                                      /* read the tpqn value from the screen  */
  1826.  
  1827.       if (read_kb(tpqn_s,3) == 0) {
  1828.  
  1829.          outmsg(USERINPUT,CLEARSCRN);   /* Clear the screen                     */
  1830.  
  1831.          tpqn = atoi(tpqn_s);           /* convert string to integer            */
  1832.  
  1833.          switch(tpqn) {
  1834.             case 48:                     /* check to see that multiple of 24    */
  1835.             case 72:
  1836.             case 96:
  1837.             case 120:
  1838.             case 144:
  1839.             case 168:
  1840.             case 192:
  1841.             case 216:
  1842.             case 240:
  1843.             case 264:
  1844.             case 288:
  1845.             case 312:
  1846.             case 336:
  1847.             case 360:
  1848.             case 384:
  1849.                tpqn_not_valid = FALSE;
  1850.                break;
  1851.             default:
  1852.                outmsg(WARNING,TPQNVAL);  /* not a valid value - give 'em help   */
  1853.                break;
  1854.          } /* end switch(tpqn) */
  1855.  
  1856.       } else {
  1857.  
  1858.          ch = ESC;
  1859.          return(-1);
  1860.  
  1861.       } /* endif ch != ESC */
  1862.  
  1863.    } /* endwhile */
  1864.  
  1865.    outmsg(WARNING,CLEARSCRN);         /* clear any warning message that may  */
  1866.                                       /* have been displayed                 */
  1867.  
  1868.    /* put requested counts into timinit to tell the device driver and also   */
  1869.    /* save it in the header chunk for the MIDI file.                         */
  1870.    timinitr[7] = (unsigned char)((tpqn / 24)-1);
  1871.    header[12] = (char)(tpqn & 0xFF00);
  1872.    header[13] = (char)(tpqn & 0xFF);
  1873.  
  1874.    /**************************************************************************/
  1875.    /* Enable timing data and ppqn - would only get here if MIDI mode         */
  1876.    /**************************************************************************/
  1877.    dcwrite(timinitr,10,1);
  1878.  
  1879.    outmsg(USERINPUT,CLEARSCRN);
  1880.  
  1881.    /**************************************************************************/
  1882.    /* Write out Header Chunk                                                 */
  1883.    /**************************************************************************/
  1884.  
  1885.    if ((ndata = (unsigned)write(inhndl,(char *)header,14)) != 14) {
  1886.  
  1887.      outmsg(HELP,CLEARSCRN);
  1888.      outmsg(ERROR,DISKFULL);
  1889.      _settextposition(10,30);
  1890.      printf("%s", iname);
  1891.      endemsg(ERROR);
  1892.      return (1);
  1893.  
  1894.    } /* endif fwrite */
  1895.  
  1896.    /**************************************************************************/
  1897.    /* Write out Track Chunk                                                  */
  1898.    /**************************************************************************/
  1899.  
  1900.    if ((ndata = (unsigned)write(inhndl,(char *)track,8)) != 8) {
  1901.  
  1902.      outmsg(HELP,CLEARSCRN);
  1903.      outmsg(ERROR,DISKFULL);
  1904.      _settextposition(10,30);
  1905.      printf("%s", iname);
  1906.      endemsg(ERROR);
  1907.      return (1);
  1908.  
  1909.    } /* endif fwrite */
  1910.  
  1911.    /* Write MEDA event to set tempo                                          */
  1912.  
  1913.    /* calculate the times per beat        */
  1914.    tttttt = 600000000 / ((tpqn*10) & 0x3FFF);
  1915.  
  1916.    /* put result into conv_buf           */
  1917.    tempo_meda[6] = (unsigned char)(tttttt & 0x000000FF);
  1918.    tempo_meda[5] = (unsigned char)((tttttt >> 8) & 0x000000FF);
  1919.    tempo_meda[4] = (unsigned char)((tttttt >> 16) & 0x000000FF);
  1920.  
  1921.    if ((ndata = (unsigned)write(inhndl,(char *)tempo_meda,7)) != 7) {
  1922.  
  1923.      outmsg(HELP,CLEARSCRN);
  1924.      outmsg(ERROR,DISKFULL);
  1925.      _settextposition(10,30);
  1926.      printf("%s", iname);
  1927.      endemsg(ERROR);
  1928.      return (1);
  1929.  
  1930.    } /* endif fwrite */
  1931.  
  1932.    return (0);
  1933.  
  1934. } /* end write_midi_headers */
  1935.  
  1936. /*****************************************************************************/
  1937. /*                                                                           */
  1938. /*      FUNCTION NAME = write_riff_lengths                                   */
  1939. /*                                                                           */
  1940. /*      FUNCTION = write RIFF chunk lengths                                  */
  1941. /*                                                                           */
  1942. /*      INPUT PARAMETERS = none                                              */
  1943. /*                                                                           */
  1944. /*      RETURN CODE = 0 Successful                                           */
  1945. /*                    1 Failure                                              */
  1946. /*                                                                           */
  1947. /*****************************************************************************/
  1948.  
  1949. int write_riff_lengths(void)             /* Begin Function                   */
  1950. {
  1951.  
  1952. /*****************************************************************************/
  1953. /*                   LOCAL VARIABLE DEFINITIONS                              */
  1954. /*****************************************************************************/
  1955. unsigned long   chunk_len=0;       /* length of chunk                        */
  1956.  
  1957.    /* determine length of data chunk =                                    */
  1958.    /*   Position                        file length                       */
  1959.    /*    0                            - RIFF chunk ID (4 bytes)           */
  1960.    /*    4                            - chunk length  (4 bytes)           */
  1961.    /*    8                            - WAVE chunk ID (4 bytes)           */
  1962.    /*    12                           - fmt  chunk ID (4 bytes)           */
  1963.    /*    16                           - chunk length  (4 bytes)           */
  1964.    /*    20                           - waveformat structure (16 bytes)   */
  1965.    /*    36                           - data chunk id (4 bytes)           */
  1966.    /*    40                           - chunk length  (4 bytes)           */
  1967.  
  1968.    /* write RIFF chunk length to file                                     */
  1969.    chunk_len = filelength(inhndl) - 8;
  1970.                        /* Position marker to data chunk length in file    */
  1971.    lseek(inhndl,4,SEEK_SET);
  1972.    if ((unsigned)write(inhndl,(char *)&chunk_len,4) != 4) {
  1973.  
  1974.      outmsg(HELP,CLEARSCRN);
  1975.      outmsg(ERROR,DISKFULL);
  1976.      _settextposition(10,30);
  1977.      printf("%s", iname);
  1978.      endemsg(ERROR);
  1979.      return (1);
  1980.  
  1981.    } /* endif write */
  1982.  
  1983.    /* write 'data' chunk length to file                                   */
  1984.    chunk_len -= 36; /* WAVE and length shorter than WAVE chunk & fmt chunk*/
  1985.                     /* Position marker to data chunk length in file       */
  1986.    lseek(inhndl,40,SEEK_SET);
  1987.    if ((unsigned)write(inhndl,(char *)&chunk_len,4) != 4) {
  1988.  
  1989.      outmsg(HELP,CLEARSCRN);
  1990.      outmsg(ERROR,DISKFULL);
  1991.      _settextposition(10,30);
  1992.      printf("%s", iname);
  1993.      endemsg(ERROR);
  1994.      return (1);
  1995.  
  1996.    } /* endif write */
  1997.  
  1998.    /* write 'fmt ' chunk length to file                                   */
  1999.    chunk_len = 16;     /* WAVE and length shorter than WAVE chunk         */
  2000.                        /* Position marker to data chunk length in file    */
  2001.    lseek(inhndl,16,SEEK_SET);
  2002.    if ((unsigned)write(inhndl,(char *)&chunk_len,4) != 4) {
  2003.  
  2004.      outmsg(HELP,CLEARSCRN);
  2005.      outmsg(ERROR,DISKFULL);
  2006.      _settextposition(10,30);
  2007.      printf("%s", iname);
  2008.      endemsg(ERROR);
  2009.      return (1);
  2010.  
  2011.    } /* endif write */
  2012.  
  2013.    return(0);
  2014.  
  2015. } /* end write_riff_lengths() */
  2016.  
  2017. /*****************************************************************************/
  2018. /*                                                                           */
  2019. /*      FUNCTION NAME = write_midi_lengths                                   */
  2020. /*                                                                           */
  2021. /*      FUNCTION = write MIDI track lengths and ending meda events           */
  2022. /*                                                                           */
  2023. /*      INPUT PARAMETERS = none                                              */
  2024. /*                                                                           */
  2025. /*      RETURN CODE = 0 Successful                                           */
  2026. /*                    1 Failure                                              */
  2027. /*                                                                           */
  2028. /*****************************************************************************/
  2029.  
  2030. int write_midi_lengths(void)             /* Begin Function                   */
  2031. {
  2032.  
  2033. /*****************************************************************************/
  2034. /*                   LOCAL VARIABLE DEFINITIONS                              */
  2035. /*****************************************************************************/
  2036. int             ndata;
  2037. unsigned long   chunk_len=0;       /* length of chunk                        */
  2038.  
  2039.  
  2040.    /***********************************************************************/
  2041.    /* Write out End of Track MEDA event                                   */
  2042.    /***********************************************************************/
  2043.  
  2044.    if ((ndata = (unsigned)write(inhndl,(char *)eot_meda,4)) != 4) {
  2045.  
  2046.      outmsg(HELP,CLEARSCRN);
  2047.      outmsg(ERROR,DISKFULL);
  2048.      _settextposition(10,30);
  2049.      printf("%s", iname);
  2050.      endemsg(ERROR);
  2051.      return (1);
  2052.  
  2053.    } /* endif fwrite */
  2054.  
  2055.    /* determine length of track chunk =                                   */
  2056.    /*                                   file length                       */
  2057.    /*                                 - header chunk (14 bytes)           */
  2058.    /*                                 - track chunk first 8 bytes         */
  2059.    chunk_len = filelength(inhndl) - 14 - 8;
  2060.    track[7] = (unsigned char)(chunk_len & 0xFF);
  2061.    chunk_len >>= 8;
  2062.    track[6] = (unsigned char)(chunk_len & 0xFF);
  2063.    chunk_len >>= 8;
  2064.    track[5] = (unsigned char)(chunk_len & 0xFF);
  2065.    chunk_len >>= 8;
  2066.    track[4] = (unsigned char)(chunk_len & 0xFF);
  2067.  
  2068.    lseek(inhndl,14,SEEK_SET);        /* Go to the beginning of the file  */
  2069.                                       /* to write in length of the track  */
  2070.                                       /* chunk.                           */
  2071.    /***********************************************************************/
  2072.    /* Write out Track Chunk                                               */
  2073.    /***********************************************************************/
  2074.  
  2075.    if ((ndata = (unsigned)write(inhndl,(char *)track,8)) != 8) {
  2076.  
  2077.      outmsg(HELP,CLEARSCRN);
  2078.      outmsg(ERROR,DISKFULL);
  2079.      _settextposition(10,30);
  2080.      printf("%s", iname);
  2081.      endemsg(ERROR);
  2082.      return (1);
  2083.  
  2084.    } /* endif write */
  2085.  
  2086.    return(0);
  2087.  
  2088. } /* end write_midi_lengths() */
  2089.  
  2090. /*****************************************************************************/
  2091. /*                                                                           */
  2092. /*      FUNCTION NAME = audplay                                              */
  2093. /*                                                                           */
  2094. /*      FUNCTION = play file                                                 */
  2095. /*                                                                           */
  2096. /*      INPUT PARAMETERS = none                                              */
  2097. /*                                                                           */
  2098. /*      RETURN CODE = 0 Successful                                           */
  2099. /*                    1 Failure                                              */
  2100. /*                                                                           */
  2101. /*****************************************************************************/
  2102.  
  2103. int audplay(void)                        /* Begin Function                   */
  2104. {
  2105.  
  2106. /*****************************************************************************/
  2107. /*                   LOCAL VARIABLE DEFINITIONS                              */
  2108. /*****************************************************************************/
  2109. unsigned char mode_s[4];               /* Temp read buffer                   */
  2110. unsigned char form_s[4];               /* Temp read buffer                   */
  2111. unsigned long cksize;                  /* RIFF chunk size - dword            */
  2112. unsigned long bytes_read;              /* bytes read in READ function        */
  2113.  
  2114. struct waveformat_s {
  2115.    unsigned int  formattag;            /* format category                    */
  2116.    unsigned int  nchannels;            /* number of channels                 */
  2117.    unsigned long nsamplespersec;       /* sampling rate                      */
  2118.    unsigned long navgbytespersec;      /* for buffering                      */
  2119.    unsigned int  nblockalign;          /* block alignment                    */
  2120.    unsigned int  nbitspersample;       /* sample size                        */
  2121. };
  2122.  
  2123. struct waveformat_s waveformat;
  2124.  
  2125. struct   audio_hpi hpi;
  2126.  
  2127. #if IS_DOS
  2128. unsigned long data;
  2129. #endif
  2130.  
  2131.  
  2132.    wasur = 0;
  2133.  
  2134.    /* Continue, device driver was installed ok... */
  2135.  
  2136.    for (sy=0; sy<num_xbuffers_p; sy++) {
  2137.       /* Setup our own buffer */
  2138.       if ((xbuffer = (char far *)_fmalloc((size_t)xbuffer_len_p[sy]))==NULL) {
  2139.          outemsg(ERROR,MALLOCERR);      /* Write failed return code             */
  2140.          close(audhndl);
  2141.          close(inhndl);
  2142.          freebuffs(sy,0);
  2143.          return(1);
  2144.       }
  2145.       if (update_flag) {
  2146.          update_size += xbuffer_len_p[sy];
  2147.          update_array[sy].Virt = xbuffer;
  2148.          update_array[sy].length = xbuffer_len_p[sy];
  2149.          xbuf->buf[sy].Virt = NULL;
  2150.          xbuf->buf[sy].length = 0;
  2151.       } else {
  2152.          xbuf->buf[sy].Virt = xbuffer;
  2153.          xbuf->buf[sy].length = xbuffer_len_p[sy];
  2154.       } /* endif */
  2155.    } /* endfor */
  2156.  
  2157.    if (update_flag) {
  2158.       update_ptr = update_array[0].Virt;
  2159.       xbuf->size = 0;
  2160.       update_index = 0;
  2161.       prv_segnum = 0;
  2162.    } else {
  2163.       xbuf->size = xlength;
  2164.    } /* endif */
  2165.  
  2166.    xbuf->num_buffers = num_xbuffers_p;
  2167.    xbuf->head = xbuf->buf[0].Virt;
  2168.    xbuf->tail = xbuf->buf[0].Virt;
  2169.    xbuf->count = 0;
  2170.    xbuf->position = 0;
  2171.    xbuf->delay = 0;
  2172.    xbuf->runflags = cb_flag;
  2173.  
  2174.    old_tail = xbuf->tail;
  2175.  
  2176.    /* Setup our own buffer */
  2177.    if ((rbuffer = (char far *)_fmalloc((size_t)RBUFFERSIZEP))==NULL) {
  2178.       outemsg(ERROR,MALLOCERR);      /* Write failed return code             */
  2179.       close(audhndl);
  2180.       close(inhndl);
  2181.       freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2182.       return(1);
  2183.    }
  2184.    rbuf->size = RBUFFERSIZEP;
  2185.    rbuf->num_buffers = 1;
  2186.    rbuf->buf[0].Virt = rbuffer;
  2187.    rbuf->buf[0].length = RBUFFERSIZEP;
  2188.  
  2189.    rbuf->head = rbuffer;
  2190.    rbuf->tail = rbuffer;
  2191.    rbuf->count = 0;
  2192.    rbuf->position = 0;
  2193.    rbuf->delay = 0;
  2194.    rbuf->runflags = 0;
  2195.  
  2196.    if (cb_flag) {
  2197.       interrupt_count = 0;
  2198. #if IS_OS2
  2199.       hpi.cb = callback;
  2200. #else
  2201.       hpi.cb = &callback;
  2202.       data = &interrupt_count;
  2203. #if VER20
  2204.       hpi.cb_ds_val = (unsigned int)(data >> 16);
  2205. #endif
  2206. #endif
  2207.    } else {
  2208.       hpi.cb = NULL;
  2209.    } /* endif */
  2210.    hpi.newxbuf = xbuf;
  2211.    hpi.newrbuf = rbuf;
  2212.    hpi.flags = 0;
  2213.    #if IS_DOS
  2214.     if(rc = ioctl(&hpi,AUDIO_HPI,audhndl)){
  2215.    #else
  2216.     if(rc = DosDevIOCtl(&hpi, NULL, 0x40+AUDIO_HPI, 0x80, audhndl)) {
  2217.    #endif
  2218.       outmsg(ERROR,HPIIOCTL);        /* Write failed return code          */
  2219.       _settextposition(11,30);
  2220.       printf("%i",rc);
  2221.       endemsg(ERROR);
  2222.       close(audhndl);
  2223.       close(inhndl);
  2224.       freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2225.       return(1);
  2226.    }
  2227.    #if IS_DOS
  2228.     direct_call = hpi.ep;
  2229.    #endif
  2230.  
  2231.  
  2232.    /* Determine if MIDI standard file, RIFF-MIDI file, RIFF-WAVE(PCM), or */
  2233.    /* RIFF-ibmw(MU_LAW,A_LAW,ADPCM)                                       */
  2234.    read(inhndl,mode_s,4);                  /* read chunk type             */
  2235.    if ( !(strncmp(mode_s,"MThd",4) ) ) {   /* MIDI header chunk?          */
  2236.  
  2237.       lseek(inhndl,0,SEEK_SET);           /* Go back to top of file      */
  2238.       cksize = filelength(inhndl);         /* entire file is 'chunk'      */
  2239.  
  2240.       file_type = 0;
  2241.       /* Set up for INIT IOCtl */
  2242.       init.mode = MIDI;
  2243.       chan_i = NONE;
  2244.       init.srate = mode_table[0].srate_low;
  2245.       init.flags = mode_table[0].flags;
  2246.       init.bits_per_sample = mode_table[0].bps_low;
  2247.       init.bsize = mode_table[0].bsize;
  2248.       init.channels = channels;
  2249.       rc = play_data(cksize,init);
  2250.  
  2251.    } else if (!(strncmp(mode_s,"RIFF",4))) { /* RIFF header chunk?        */
  2252.  
  2253.       read(inhndl,(char *)&cksize,4);      /* read RIFF chunk size        */
  2254.       bytes_read = read(inhndl,form_s,4);  /* read formtype (WAVE)        */
  2255.  
  2256.       if ((!(strncmp(form_s,"WAVE",4)))  || /* WAVEform?                  */
  2257.           (!(strncmp(form_s,"ibmw",4)))) {  /* ibmwform?                  */
  2258.  
  2259.          while (bytes_read == 4) {         /* end of file?                */
  2260.  
  2261.             bytes_read = read(inhndl,mode_s,4);/* read fmt header id      */
  2262.  
  2263.             if ( !(strncmp(mode_s,"fmt ",4) ) ) { /* fmt chunk?           */
  2264.  
  2265.                read(inhndl,(char *)&cksize,4);     /* read fmt chunk size    */
  2266.                read(inhndl,(char *)&waveformat,16);/* read wave format chunk */
  2267.  
  2268.                if ( ( ((waveformat.formattag == 1) ||    /* Supported data?   */
  2269.                    ((waveformat.formattag >= 0x0101) &&
  2270.                     (waveformat.formattag <= 0x0103))) &&
  2271.                    (!(strncmp(form_s,"WAVE",4)))) ||
  2272.                    ((waveformat.formattag >= 2) &&
  2273.                     (waveformat.formattag <= 5) &&
  2274.                     (!(strncmp(form_s,"ibmw",4))))) {
  2275.  
  2276.  
  2277.                   bytes_read = read(inhndl,mode_s,4);/* read chunk name   */
  2278.  
  2279.                   while (bytes_read == 4) {          /* end of file ?     */
  2280.  
  2281.                      read(inhndl,(char *)&cksize,4);  /* read chunk size   */
  2282.  
  2283.                      if (!(strncmp(mode_s,"data",4))) { /* data chunk?    */
  2284.  
  2285.                         /* Set up for INIT IOCtl */
  2286.                         if (waveformat.formattag == 1) {
  2287.                            init.mode = PCM;
  2288.                            file_type = 5;
  2289.                         } else if ((waveformat.formattag == 2) ||
  2290.                                   (waveformat.formattag == 0x0101)) {
  2291.                            init.mode = MU_LAW;
  2292.                            file_type = 16;
  2293.                         } else if ((waveformat.formattag == 3) ||
  2294.                                   (waveformat.formattag == 0x0102)) {
  2295.                            init.mode = A_LAW;
  2296.                            file_type = 20;
  2297.                         } else if ((waveformat.formattag == 4) ||
  2298.                                   (waveformat.formattag == 0x0103)) {
  2299.                            init.mode = ADPCM;
  2300.                            file_type = -4; /* have 5 less than where it really */
  2301.                                        /* starts so that when the rate is */
  2302.                                        /* done - it ends up correctly */
  2303.                         } else { /* must == 5 */
  2304.                            init.mode = CVSD;
  2305.                            file_type = 25;
  2306.                         } /* endif */
  2307.                         init.srate = waveformat.nsamplespersec;
  2308.                         if (init.srate == 11025) {
  2309.                            file_type += 1;
  2310.                         } else if (init.srate == 22050) {
  2311.                            file_type += 2;
  2312.                         } else if (init.srate == 44100) {
  2313.                            if (mode == ADPCM) {
  2314.                               file_type += 4;
  2315.                            } else {
  2316.                               file_type += 3;
  2317.                            } /* endif */
  2318.                         } else if (init.srate == 7875) {
  2319.                            file_type += 26;
  2320.                         } else if (init.srate == 31500) {
  2321.                            file_type += 27;
  2322.                         } else if (init.srate == 48000) {
  2323.                            file_type += 28;
  2324.                         } /* endif */
  2325.                         init.bits_per_sample = waveformat.nbitspersample;
  2326.                         if (init.bits_per_sample == 8) {
  2327.                            init.flags = FIXED;
  2328.                         } else { /* assume 16 bits per sample */
  2329.                            init.flags = FIXED+TWOS_COMPLEMENT;
  2330.                            if (init.srate == 7875 || init.srate == 31500 ||
  2331.                                init.srate == 48000) {
  2332.                               file_type += 3;
  2333.                            } else {
  2334.                               file_type += 4;
  2335.                            } /* endif */
  2336.                         } /* endif */
  2337.                         init.bsize = BSIZE_R;
  2338.                         init.channels = waveformat.nchannels;
  2339.                         if (init.channels == 1) {
  2340.                            if (mode != ADPCM) {
  2341.                               chan_i = MONO;
  2342.                            } else {
  2343.                               chan_i = NONE;
  2344.                            } /* endif */
  2345.                         } else {
  2346.                            if (mode != ADPCM) {
  2347.                               chan_i = STEREO;
  2348.                            } else {
  2349.                               chan_i = NONE;
  2350.                               if (mode_i == AVC_MUSIC)
  2351.                                  file_type++; /* Make it AVC_STEREO if 2 channels */
  2352.                            } /* endif */
  2353.                         } /* endif */
  2354.                         rc = play_data(cksize,init);
  2355.  
  2356.                      } else { /* not data chunk */
  2357.  
  2358.                         /* ignore this chunk                                       */
  2359.                         lseek(inhndl,cksize,SEEK_CUR);
  2360.  
  2361.                      } /* endif */
  2362.  
  2363.                      /* read next chunk                                            */
  2364.                      bytes_read = read(inhndl,mode_s,4);/* read chunk name*/
  2365.  
  2366.                   } /* end while not end of file */
  2367.  
  2368.                } else { /* not supported data */
  2369.  
  2370.                   outemsg(ERROR,NOTPCMDATA);
  2371.                   close(audhndl);
  2372.                   close(inhndl);
  2373.                   freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2374.                   return(1);
  2375.  
  2376.                } /* endif waveformat.formattag == 1,2,3, or 4 */
  2377.  
  2378.             } else { /* unexpected chunk - ignore it */
  2379.  
  2380.                /* ignore this chunk                                       */
  2381.                lseek(inhndl,cksize,SEEK_CUR);
  2382.                outemsg(WARNING,UNCHUNK);
  2383.  
  2384.             } /* endif mode_s == 'fmt' */
  2385.  
  2386.             bytes_read = (long)read(inhndl,mode_s,4); /* read chunk name  */
  2387.  
  2388.          } /* end while not end of file */
  2389.  
  2390.       } else if ( !(strncmp(form_s,"RMID",4) ) ) {   /* MIDI inside RIFF? */
  2391.  
  2392.          bytes_read = read(inhndl,mode_s,4);/* read chunk name 'data'     */
  2393.  
  2394.          while (bytes_read == 4) {                /* end of file ?        */
  2395.  
  2396.             read(inhndl,(char *)&cksize,4);        /* read chunk size      */
  2397.  
  2398.             if (!(strncmp(mode_s,"data",4))) {    /* data chunk?         */
  2399.  
  2400.                /* Set up for INIT IOCtl */
  2401.                init.mode = MIDI;
  2402.                init.srate = mode_table[0].srate_low;
  2403.                init.flags = mode_table[0].flags;
  2404.                init.bits_per_sample = mode_table[0].bps_low;
  2405.                init.bsize = mode_table[0].bsize;
  2406.                init.channels = channels;
  2407.                chan_i = NONE;
  2408.                rc = play_data(cksize,init);
  2409.  
  2410.             } else { /* not data chunk */
  2411.  
  2412.                /* ignore this chunk                                       */
  2413.                lseek(inhndl,cksize,SEEK_CUR);
  2414.                outemsg(WARNING,UNCHUNK);
  2415.  
  2416.             } /* endif */
  2417.  
  2418.             /* read next chunk                                            */
  2419.             bytes_read = read(inhndl,mode_s,4);   /* read chunk name      */
  2420.  
  2421.          } /* end while not end of file */
  2422.  
  2423.       } else { /* unsupported RIFF file */
  2424.  
  2425.          outemsg(ERROR,UNSUPRIFF);
  2426.          close(audhndl);
  2427.          close(inhndl);
  2428.          freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2429.          return(1);
  2430.  
  2431.       } /* endif form_s == WAVE */
  2432.  
  2433.    } else { /* unrecognized file */
  2434.  
  2435.       outemsg(ERROR,UNRECOG);
  2436.       close(audhndl);
  2437.       close(inhndl);
  2438.       freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2439.       return(1);
  2440.  
  2441.    } /* endif mode_s == MThd */
  2442.  
  2443.    outmsg(VBHELP,CLEARSCRN);
  2444.  
  2445.    return(0);
  2446.  
  2447. } /* end AUDPLAY */
  2448.  
  2449. /*****************************************************************************/
  2450. /*                                                                           */
  2451. /*      FUNCTION NAME = play_data                                            */
  2452. /*                                                                           */
  2453. /*      FUNCTION = Sets up the audio device driver to play the recognized    */
  2454. /*                 input file.                                               */
  2455. /*                                                                           */
  2456. /*      INPUT PARAMETERS = cksize - size of chunk to be played               */
  2457. /*                         init - initialization structure                   */
  2458. /*                                                                           */
  2459. /*      RETURN CODE = 0 Successful                                           */
  2460. /*                    1 Escape from program                                  */
  2461. /*                                                                           */
  2462. /*****************************************************************************/
  2463.  
  2464. int play_data (unsigned long cksize, struct audio_init init)
  2465. {
  2466.  
  2467. /*****************************************************************************/
  2468. /*                   LOCAL VARIABLE DEFINITIONS                              */
  2469. /*****************************************************************************/
  2470. #if IS_DOS
  2471.  union REGS dosregs;
  2472. #endif
  2473. struct   audio_control control;
  2474. struct   audio_change change;
  2475. int      key_hit;
  2476. char     ch;
  2477.    /* Issue INIT IOCTL call                                                  */
  2478.    init.operation = PLAY;
  2479.    init.rc = 0;
  2480.    init.reserved = NULL;
  2481.    init.version_level = CURRENT_VERSION;
  2482.    #if IS_DOS
  2483.     if(direct_call == NULL){
  2484.       rc = ioctl(&init,AUDIO_INIT,audhndl);
  2485.     }else{
  2486.       rc = (*direct_call)(EP_INIT,(char far *)&init,23);
  2487.     }
  2488.     if (rc) {
  2489.    #else
  2490.     if(rc = DosDevIOCtl(&init, NULL, 0x40+AUDIO_INIT, 0x80, audhndl)) {
  2491.    #endif
  2492.       outmsg(ERROR,EINITIOCTL);
  2493.       _settextposition(11,30);
  2494.       printf("%i",rc);
  2495.       endemsg(ERROR);
  2496.       close(audhndl);
  2497.       close(inhndl);
  2498.       return(1);
  2499.     }
  2500.  
  2501.  
  2502.    if(init.rc != 0){
  2503.       outmsg(ERROR,INITFAILED);   /* Write failed return code                */
  2504.       _settextposition(11,30);
  2505.       printf("%i",init.rc);
  2506.       endemsg(ERROR);
  2507.       close(audhndl);
  2508.       close(inhndl);
  2509.       return(1);
  2510.    }
  2511.  
  2512.    if (init.flags & BESTFIT_PROVIDED) {
  2513.       mode = init.mode;
  2514.       channels = init.channels;
  2515.       outemsg(WARNING,BESTFIT);      /* Warn user given configuration        */
  2516.                                      /* was not supported and a best         */
  2517.                                      /* fit configuration was done           */
  2518.    } /* endif best fit was provided */
  2519.  
  2520.    if (init.flags & LOAD_CODE) {      /* Load DSP code module                */
  2521.       if (rc = dspload(&init.loadpath[0], audhndl)) {
  2522.          outmsg(ERROR,EDSPLOAD);      /* Write failed return code             */
  2523.          _settextposition(11,30);
  2524.          printf("%i",rc);
  2525.          endemsg(ERROR);
  2526.          close(audhndl);
  2527.          close(inhndl);
  2528.          return(1);
  2529.       }
  2530.    }
  2531.  
  2532.    /* Issue CHANGE IOCtl */
  2533.    control.position = 0;                     /* Do it now                    */
  2534.    control.ioctl_request = AUDIO_CHANGE;     /* Change configuration         */
  2535.    control.return_code = 0;                  /* zero out return code field   */
  2536.    control.request_info = &change;           /* Request data = change struct */
  2537.    change.input_list[0].devtype = 0;
  2538.    change.input_list[0].devnum  = DEVICE_1;
  2539.    change.output_list[0].devtype = source_output;
  2540.    change.output_list[0].devnum  = DEVICE_1;
  2541.    change.input_list[1].devtype = NULL_INPUT;
  2542.    change.input_list[1].devnum  = DEVICE_1;
  2543.    change.output_list[1].devtype = NULL_OUTPUT;
  2544.    change.output_list[1].devnum  = DEVICE_1;
  2545.    change.input = INPUTS_LISTED;
  2546.    change.output = OUTPUTS_LISTED;           /* Output select              */
  2547.    change.monitor = monitor;                 /* Monitor not applicable       */
  2548.    cur_volume = 0x7fffffff;
  2549.    change.volume = cur_volume;               /* Volume set to maximum        */
  2550.    change.volume_delay = delay;              /* Set volume now               */
  2551.    change.balance = cur_balance;             /* Balance set to mid-point     */
  2552.    change.balance_delay = delay;             /* Set balance now              */
  2553.    change.treble = 0x3fffffff;               /* Mid point                    */
  2554.    change.bass = 0x3fffffff;                 /* Mid point                    */
  2555.    change.pitch = 0;                         /*                              */
  2556.  
  2557.    if (mastervol) {
  2558.    change.dev_info = &devinfo;               /* Device dependent data      */
  2559.    } else {
  2560.    change.dev_info = NULL;                   /* No device dependent data   */
  2561.    }
  2562.    change.input_gain = 0;                    /* No input gain              */
  2563.    change.mode_info = NULL;                  /* No mode dependent data     */
  2564.  
  2565.    #if IS_DOS
  2566.     if(direct_call == NULL){
  2567.       rc = ioctl(&control,AUDIO_CONTROL,audhndl);
  2568.     }else{
  2569.       rc = (*direct_call)(EP_CONTROL,(char far *)&control,23);
  2570.     }
  2571.  
  2572.     /*************************************************************************/
  2573.     /* Issue IOCTL set device parameters to force BINARY mode                */
  2574.     /* (otherwise an 0x1a read will cause DOS to assume EOF)                 */
  2575.     /* You might need to uncomment this if you want to build                 */
  2576.     /* a DOS only version.                                                   */
  2577.     /*************************************************************************/
  2578.     dosregs.x.ax=0x4401;
  2579.     dosregs.x.bx=audhndl;
  2580.     dosregs.x.dx=0x00a0;
  2581.     intdos(&dosregs,&dosregs);
  2582.     /*************************************************************************/
  2583.     if (rc) {
  2584.    #else
  2585.     if(rc = DosDevIOCtl(&control, NULL, 0x40+AUDIO_CONTROL, 0x80, audhndl)) {
  2586.    #endif
  2587.       outmsg(ERROR,ECHNGIOCTL);
  2588.       _settextposition(11,30);
  2589.       printf("%i",rc);
  2590.       endemsg(ERROR);
  2591.       close(audhndl);
  2592.       close(inhndl);
  2593.       return(1);
  2594.     }
  2595.  
  2596.    if (init.mode == MIDI) {
  2597.       /* Enable timing data, and 48ppqn.                                  */
  2598.       /* Disable input clocks                                             */
  2599.       dcwrite(timinit,10,num_xbuffers_p);
  2600.    } /* endif */
  2601.  
  2602.    outmsg(USERINPUT,CLEARSCRN);
  2603.    outmsg(HELP,BLANK);
  2604.    outmsg(HELP,PLAYING1);
  2605.    _settextposition(9,((short)(strlen(help_msg[PLAYING1][0]))+5));
  2606.    printf("%s - %s %s",iname,file_type_msg[file_type],mono_stereo_msg[chan_i]);
  2607.    _settextposition(10,((short)(strlen(help_msg[PLAYING1][1]))+5));
  2608.    printf("%s",audioname);
  2609.    if (pos_flag) {
  2610.       _settextposition(11,5);
  2611.       _setbkcolor(AQUA);       /* Set background color            */
  2612.       _settextcolor(BLACK);    /* Set foreground/text color       */
  2613.       _outtext(extra_msg[POSITION]);
  2614.    } /* endif */
  2615.    if (cb_flag) {
  2616.       _settextposition(17,5);
  2617.       _setbkcolor(AQUA);       /* Set background color            */
  2618.       _settextcolor(BLACK);    /* Set foreground/text color       */
  2619.       _outtext(extra_msg[CBCOUNT]);
  2620.    } /* endif */
  2621.    _settextposition(13,((short)(strlen(help_msg[PLAYING1][4]))+5));
  2622.    printf("%s",cur_volume_s);
  2623.    _settextposition(14,((short)(strlen(help_msg[PLAYING1][5]))+5));
  2624.    printf("%s",cur_balance_s);
  2625.    outmsg(STATUS,STARTSTOP);
  2626.    outmsg(VBHELP,VOLBAL);
  2627.    started = 0;
  2628.  
  2629.    if (init.mode == MIDI) {
  2630.       /* Start getting data from MIDI file and playing it                 */
  2631.       rc=midi2seq(cksize);
  2632.    } else {
  2633.       /* Start getting data from RIFF-PCM file and playing it             */
  2634.       rc=send_data(mode_s,cksize,inhndl);       /* note mode_s dummy var  */
  2635.  
  2636. #if IS_OS2
  2637.       rc = DosSetPrty(0,1,0,PidInfo.pid);
  2638. #endif
  2639.  
  2640.       if (audiowait) {
  2641.          while (!(xbuf->runflags & STARTED))
  2642.             key_hit=send_data(&ch,0,0);    /* Waste time waiting to start */
  2643.          #if IS_DOS
  2644.           if(rc = ioctl(0,AUDIO_WAIT,audhndl)){
  2645.          #else
  2646.           if(rc = DosDevIOCtl(0, NULL, 0x40+AUDIO_WAIT, 0x80, audhndl)) {
  2647.          #endif
  2648.             outmsg(ERROR,WAITIOCTL);      /* Write failed return code             */
  2649.             _settextposition(11,30);
  2650.             printf("%i",rc);
  2651.             endemsg(ERROR);
  2652.             close(audhndl);
  2653.             close(inhndl);
  2654.             freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2655.             return(1);
  2656.          }
  2657.          update_count();
  2658.          /* loop until get ESC character */
  2659.          while(!user_esc) {
  2660.            if (kbhit()) {
  2661.               key_hit = getch();
  2662.               if (key_hit == ESC) user_esc = TRUE;
  2663.            }
  2664.          }
  2665.       } else {
  2666.          while (!user_esc) {
  2667.             key_hit=send_data(&ch,0,0);    /* Waste time for music to finish*/
  2668.                                             /* or for user to press ESCape   */
  2669.             update_count();
  2670.             if ((xbuf->count <= blocksize*2)) {
  2671.                strcpy(status,"Finished");
  2672.                _settextposition(12,((short)(strlen(help_msg[PLAYING1][3]))+5));
  2673.                printf("%s",status);
  2674.                if (old_runtotal != runtotal) {
  2675.                   old_runtotal = runtotal;
  2676.                   _settextposition(16,((short)(strlen(help_msg[PLAYING1][7]))+5));
  2677.                   printf("%6.6ld",runtotal);
  2678.                } /* endif */
  2679.                if (batch) user_esc = TRUE;
  2680.  
  2681.                if (!batch) {
  2682.                   /* loop until get ESC character */
  2683.                   while(!user_esc) {
  2684.                      if (kbhit()) {
  2685.                         key_hit = getch();
  2686.                         if (key_hit == ESC) user_esc = TRUE;
  2687.                      }
  2688.                      if (!supress) {
  2689.                         if (old_playtotal != playtotal) {
  2690.                            _settextposition(15,((short)(strlen(help_msg[PLAYING1][6]))+5));
  2691.                            printf("%6.6ld",playtotal);
  2692.                            old_playtotal = playtotal;
  2693.                         } /* endif */
  2694.                         if (pos_flag) {
  2695.                            _settextposition(11,((short)(strlen(extra_msg[POSITION]))+5));
  2696.                            printf("%6.6ld",xbuf->position);
  2697.                         } /* endif */
  2698.                         if (cb_flag) {
  2699.                            _settextposition(17,((short)(strlen(extra_msg[CBCOUNT]))+5));
  2700.                            printf("%6.6ld",interrupt_count);
  2701.                         } /* endif */
  2702.  
  2703.                      } /* endif */
  2704.                   }
  2705.                } /* endif */
  2706.             } /* endif */
  2707.          } /* end_while */
  2708.       } /* endif */
  2709.  
  2710. #if IS_OS2
  2711.       rc = DosSetPrty(2,1,priority,PidInfo.pid);
  2712. #endif
  2713.  
  2714.    } /* endif */                                /* for call               */
  2715.  
  2716.    outmsg(HELP,CLEARSCRN);
  2717.  
  2718.    return(rc);
  2719.  
  2720. } /* end PLAY_DATA */
  2721.  
  2722. /*****************************************************************************/
  2723. /*                                                                           */
  2724. /*      FUNCTION NAME = senddata                                             */
  2725. /*                                                                           */
  2726. /*      FUNCTION = Writes data from converted MIDI file to the audio device  */
  2727. /*                 and checks for any input from the user via keyboard.      */
  2728. /*                                                                           */
  2729. /*      INPUT PARAMETERS = data - buffer with data to be written             */
  2730. /*                         count - number of bytes to be written from data   */
  2731. /*                         instring - file handle (used for RIFF files)      */
  2732. /*                                                                           */
  2733. /*      RETURN CODE = 0 Successful                                           */
  2734. /*                    1 Escape from program                                  */
  2735. /*                                                                           */
  2736. /*****************************************************************************/
  2737.  
  2738. int send_data (unsigned char *data, unsigned long count, int instring)
  2739. {
  2740.  
  2741. /*****************************************************************************/
  2742. /*                   LOCAL VARIABLE DEFINITIONS                              */
  2743. /*****************************************************************************/
  2744. unsigned char *tdata;        /* temp ptr to data */
  2745. int           ch=0;
  2746. unsigned long write_num;
  2747. char wrap_it;
  2748. struct   audio_update update;
  2749. unsigned char last_one;
  2750. unsigned int num_returned;
  2751.  
  2752.    tdata = data;
  2753.    do {
  2754.  
  2755.       if (update_flag) {
  2756.          /* See how much room is available in the update_array */
  2757.          write_num = update_size - update_cnt;
  2758.          if(write_num > 0x7fff) write_num = 0x7fff;       /* Limit to int range */
  2759.  
  2760.          /* Don't allow fread to wrap around the buffer     */
  2761.  
  2762.          if(write_num >= (unsigned long)(update_array[update_segnum].Virt-update_ptr
  2763.                                +update_array[update_segnum].length)){
  2764.             write_num = (unsigned long)(update_array[update_segnum].Virt-update_ptr
  2765.                                +update_array[update_segnum].length);
  2766.             wrap_it = TRUE;
  2767.          } else {
  2768.             wrap_it = FALSE;
  2769.          }
  2770.  
  2771.          /* make sure room in buffer for everything to be written               */
  2772.          if (write_num >= count) {
  2773.             write_num = count;
  2774.             last_one = 1;
  2775.          } else {
  2776.             last_one = 0;
  2777.          } /* endif */
  2778.  
  2779.          if (write_num > 0) {
  2780.  
  2781.             if (init.mode == MIDI) {
  2782.  
  2783.                outmsg(ERROR,EUPDATEMIDI);
  2784.                close(audhndl);
  2785.                close(inhndl);
  2786.                freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2787.                return(1);
  2788.  
  2789.             } else { /* RIFF-PCM */
  2790.  
  2791.                /* Fill up the buffer directly from the RIFF file            */
  2792.                read(instring,(char *)update_ptr,(unsigned int)write_num);
  2793.                available_buffs++;
  2794.  
  2795.             } /* endif */
  2796.  
  2797.             /* Adjust length of buffer for the last buffer sent down in */
  2798.             /* case it wasn't filled completely                         */
  2799.             if (last_one) {
  2800.                update_array[update_segnum].length = write_num;
  2801.             } /* endif */
  2802.             tdata += write_num; /* reposition just in case entire msg didn't fit */
  2803.             if (wrap_it) {
  2804.                if (++update_segnum >= num_xbuffers_p) {
  2805.                   update_segnum = 0;
  2806.                } /* endif */
  2807.                update_ptr = update_array[update_segnum].Virt;
  2808.             } else {
  2809.                update_ptr += write_num;
  2810.             } /* endif */
  2811.  
  2812.             update_cnt += write_num;
  2813.  
  2814.          } else {
  2815.             write_num = 0;
  2816.          } /* endif write_num > 0 */
  2817.  
  2818.          count -= write_num;            /* update number of bytes left to write */
  2819.  
  2820.          while ((available_buffs) || (xbuf->tail_segnum != prv_segnum)) {
  2821.  
  2822.             /* Set up for UPDATE IOCtl */
  2823.             update.iobuf_type = 0;                    /* XMIT buffer type        */
  2824.             if (available_buffs) {
  2825.                update.buffer_address = update_array[update_index].Virt;
  2826.                update.buffer_length  = update_array[update_index].length;
  2827.                if (++update_index >= num_xbuffers_p)
  2828.                   update_index = 0;
  2829.                available_buffs--;
  2830.             } else {
  2831.                update.buffer_address = NULL;
  2832.                update.buffer_length  = 0;
  2833.             } /* endif */
  2834.  
  2835.             if (xbuf->tail_segnum == prv_segnum) {
  2836.                num_returned = 0;
  2837.             } else {
  2838.                 if (prv_segnum < xbuf->tail_segnum) {
  2839.                    num_returned = xbuf->tail_segnum - prv_segnum;
  2840.                 } else {
  2841.                   num_returned = num_xbuffers_p - prv_segnum + xbuf->tail_segnum;
  2842.                 } /* endif */
  2843.                 /* tail segnum always equals zero after AUDIO_UPDATE for xmit */
  2844.                 prv_segnum = 0;
  2845.             } /* endif */
  2846.  
  2847.             #if IS_DOS
  2848.              if(direct_call == NULL){
  2849.                rc = ioctl(&update,AUDIO_UPDATE,audhndl);
  2850.              }else{
  2851.                rc = (*direct_call)(EP_UPDATE,(char far *)&update,23);
  2852.              }
  2853.              if (rc) {
  2854.             #else
  2855.              if(rc = DosDevIOCtl(&update, NULL, 0x40+AUDIO_UPDATE, 0x80, audhndl)) {
  2856.             #endif
  2857.                outmsg(ERROR,EUPDATEIOCTL);
  2858.                _settextposition(11,30);
  2859.                printf("%i",rc);
  2860.                endemsg(ERROR);
  2861.                close(audhndl);
  2862.                close(inhndl);
  2863.                freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  2864.                return(1);
  2865.              }
  2866.  
  2867.             while (num_returned) {
  2868.                update_cnt -= update_array[rtn_segnum].length;
  2869.                if (++rtn_segnum >= num_xbuffers_p)
  2870.                   rtn_segnum = 0;
  2871.                num_returned--;
  2872.             } /* endwhile */
  2873.  
  2874.             runtotal += update.buffer_length;
  2875.  
  2876.          } /* endwhile */
  2877.  
  2878.  
  2879. //       update_count();  Not valid calculation when AUDIO_UPDATE is used
  2880.  
  2881.       } else { /* not using AUDIO_UPDATE */
  2882.  
  2883.          /* See how much room is available in the MIDI queue */
  2884.          write_num = xbuf->size - xbuf->count;
  2885.          if(write_num > 0x7fff) write_num = 0x7fff;       /* Limit to int range */
  2886.  
  2887.          /* make sure room in buffer for everything to be written               */
  2888.          if (write_num >= count) write_num = count;
  2889.  
  2890.          /* Don't allow fread to wrap around the buffer     */
  2891.  
  2892.          if(write_num >= (unsigned long)(xbuf->buf[xbuf->head_segnum].Virt-xbuf->head
  2893.                                +xbuf->buf[xbuf->head_segnum].length)){
  2894.             write_num = (unsigned long)(xbuf->buf[xbuf->head_segnum].Virt-xbuf->head
  2895.                                +xbuf->buf[xbuf->head_segnum].length);
  2896.             wrap_it = TRUE;
  2897.          } else {
  2898.             wrap_it = FALSE;
  2899.          }
  2900.  
  2901.          if (write_num > 0) {
  2902.  
  2903.             if (init.mode == MIDI) {
  2904.  
  2905.                /* Fill up the buffer by putting converted data from 'data' into */
  2906.                /* 'xbuf'                                                        */
  2907.                memcpy((unsigned char *)xbuf->head,tdata,(int)write_num);
  2908.  
  2909.             } else { /* RIFF-PCM */
  2910.  
  2911.                /* Fill up the buffer directly from the RIFF file                */
  2912.                read(instring,(char *)xbuf->head,(unsigned int)write_num);
  2913.  
  2914.             } /* endif */
  2915.  
  2916.             tdata += write_num; /* reposition just in case entire msg didn't fit */
  2917.             if (wrap_it) {
  2918.                if (++xbuf->head_segnum >= num_xbuffers_p) {
  2919.                   xbuf->head_segnum = 0;
  2920.                } /* endif */
  2921.                xbuf->head = xbuf->buf[xbuf->head_segnum].Virt;
  2922.             } else {
  2923.                xbuf->head += write_num;
  2924.             } /* endif */
  2925.             xbuf->runflags |= IOBUF_LOCK;
  2926.             xbuf->count += write_num;
  2927.             xbuf->runflags &= ~IOBUF_LOCK;
  2928.  
  2929.             runtotal += write_num;
  2930.  
  2931.          } else {
  2932.             write_num = 0;
  2933.          } /* endif write_num > 0 */
  2934.  
  2935.          update_count();
  2936.  
  2937.          count -= write_num;            /* update number of bytes left to write */
  2938.  
  2939.       } /* endif */
  2940.  
  2941.       /* Any input data? */
  2942.       if(rbuf->count){
  2943.          outmsg(WARNING,BLANK);
  2944.          outmsg(WARNING,DISCARD);
  2945.          _settextposition(19,((short)(strlen(warning_msg[DISCARD][1]))+5));
  2946.          printf("%i",rbuf->count);
  2947.          rbuf->tail = rbuf->head;
  2948.          rbuf->runflags |= IOBUF_LOCK;
  2949.          rbuf->count = 0;
  2950.          rbuf->runflags &= ~IOBUF_LOCK;
  2951.       }
  2952.  
  2953.       if (batch && !started) {
  2954.          started = 1;
  2955.          xbuf->runflags |= STARTED;
  2956.          strcpy(status,"Running ");
  2957.       } /* endif */
  2958.  
  2959.       /**************************/
  2960.       /* Process keyboard input */
  2961.       /**************************/
  2962.       if (kbhit()) {
  2963.  
  2964.          ch=getch();
  2965.  
  2966.          switch(ch) {
  2967.  
  2968.             case ' ':
  2969.                  if (!started) {            /* if not started, issue START   */
  2970.                     started = 1;
  2971.                     xbuf->runflags |= STARTED;
  2972.                     strcpy(status,"Running ");
  2973.                  } else if (started==1) {   /* if running, issue PAUSE       */
  2974.                     started=2;
  2975.                     xbuf->runflags |= PAUSED;
  2976.                     strcpy(status,"Paused  ");
  2977.                  } else {                   /* if paused, issue RESUME       */
  2978.                     started = 1;
  2979.                     xbuf->runflags &= ~PAUSED;
  2980.                     strcpy(status,"Resumed ");
  2981.                  }
  2982.                  break;
  2983.  
  2984.             case 'r':                       /* Balance Right                 */
  2985.             case 'R':
  2986.                cur_balance = 0x7fffffff;
  2987.                strcpy(cur_balance_s,"Right ");
  2988.                change_settings();
  2989.                break;
  2990.  
  2991.             case 'L':                       /* Balance Left                  */
  2992.             case 'l':
  2993.                cur_balance = 0;
  2994.                strcpy(cur_balance_s,"Left  ");
  2995.                change_settings();
  2996.                break;
  2997.  
  2998.             case 'm':                       /* Balance Middle                */
  2999.             case 'M':
  3000.                cur_balance = 0x3fffffff;
  3001.                strcpy(cur_balance_s,"Middle");
  3002.                change_settings();
  3003.                break;
  3004.  
  3005.             case '0':                       /* Volume Settings (0 - 9)       */
  3006.                strcpy(cur_volume_s,"*---------");
  3007.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3008.                change_settings();
  3009.                break;
  3010.  
  3011.             case '1':
  3012.                strcpy(cur_volume_s,"-*--------");
  3013.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3014.                change_settings();
  3015.                break;
  3016.  
  3017.             case '2':
  3018.                strcpy(cur_volume_s,"--*-------");
  3019.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3020.                change_settings();
  3021.                break;
  3022.  
  3023.             case '3':
  3024.                strcpy(cur_volume_s,"---*------");
  3025.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3026.                change_settings();
  3027.                break;
  3028.  
  3029.             case '4':
  3030.                strcpy(cur_volume_s,"----*-----");
  3031.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3032.                change_settings();
  3033.                break;
  3034.  
  3035.             case '5':
  3036.                strcpy(cur_volume_s,"-----*----");
  3037.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3038.                change_settings();
  3039.                break;
  3040.  
  3041.             case '6':
  3042.                strcpy(cur_volume_s,"------*---");
  3043.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3044.                change_settings();
  3045.                break;
  3046.  
  3047.             case '7':
  3048.                strcpy(cur_volume_s,"-------*--");
  3049.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3050.                change_settings();
  3051.                break;
  3052.  
  3053.             case '8':
  3054.                strcpy(cur_volume_s,"--------*-");
  3055.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3056.                change_settings();
  3057.                break;
  3058.  
  3059.             case '9':
  3060.                strcpy(cur_volume_s,"---------*");
  3061.                cur_volume = (0x7fffffff/9) * (ch-'0');
  3062.                change_settings();
  3063.                break;
  3064.             case ESC:                       /* Esc = quit                    */
  3065.                  xbuf->runflags &= ~STARTED;
  3066.                  strcpy(status,"Stopped ");
  3067.                  xbuf->count = 0;
  3068.                  xbuf->head_segnum = 0;
  3069.                  xbuf->tail_segnum = 0;
  3070.                  xbuf->head = xbuf->tail = xbuf->buf[0].Virt;
  3071.                  started = 1;
  3072.                  user_esc = TRUE;
  3073.                  break;
  3074.  
  3075.             default:
  3076.                  break;
  3077.  
  3078.          } /* end switch (ch) */
  3079.  
  3080.          _settextposition(12,((short)(strlen(help_msg[PLAYING1][3]))+5));
  3081.          printf("%s",status);
  3082.  
  3083.       } /* endif keyboard hit */
  3084.  
  3085.       if (xbuf->runflags & IOB_UNDERRUN) {
  3086.          wasur = 1;
  3087.          outmsg(WARNING,UNDERRUN);
  3088.          xbuf->runflags &= ~IOB_UNDERRUN;
  3089.       } else if (wasur) {
  3090.          wasur = 0;
  3091.          outmsg(WARNING,CLEARSCRN);
  3092.       } /* endif */
  3093.  
  3094. #if IS_OS2
  3095.       if (cb_flag && (xbuf->count == xbuf->size) && (count)) {
  3096.          /* wait for semaphore to be cleared before writing more data */
  3097.          rc = DosSemSetWait(callback,50);
  3098.          if (rc) {
  3099.             error_count++;
  3100.          } else {
  3101.             interrupt_count++;
  3102.          } /* endif */
  3103.       } /* endif */
  3104. #endif
  3105.  
  3106.       if (!supress) {
  3107.          if (old_runtotal != runtotal) {
  3108.             old_runtotal = runtotal;
  3109.             _settextposition(16,((short)(strlen(help_msg[PLAYING1][7]))+5));
  3110.             printf("%6.6ld",runtotal);
  3111.          } /* endif */
  3112.          if (pos_flag) {
  3113.             _settextposition(11,((short)(strlen(extra_msg[POSITION]))+5));
  3114.             printf("%6.6ld",xbuf->position);
  3115.          } /* endif */
  3116.          if (cb_flag) {
  3117.             _settextposition(17,((short)(strlen(extra_msg[CBCOUNT]))+5));
  3118.             printf("%6.6ld",interrupt_count);
  3119.          } /* endif */
  3120.       } /* endif */
  3121.  
  3122.    } while ((count > 0) &&   /* Keep looping until all data was written      */
  3123.             (!(user_esc)));       /* or the user wants to end the program    */
  3124.  
  3125.    return(ch);
  3126.  
  3127. } /* end send_data */
  3128.  
  3129. /*****************************************************************************/
  3130. /*                                                                           */
  3131. /*      FUNCTION NAME = update_count                                         */
  3132. /*                                                                           */
  3133. /*      FUNCTION = Will calculate amount of data acutally played and output  */
  3134. /*                 it to the screen.                                         */
  3135. /*                                                                           */
  3136. /*      INPUT PARAMETERS =                                                   */
  3137. /*                                                                           */
  3138. /*      RETURN CODE = 0 Successful                                           */
  3139. /*                    1 Failure                                              */
  3140. /*                                                                           */
  3141. /*****************************************************************************/
  3142.  
  3143. void update_count(void)   /* Begin Function                  */
  3144. {
  3145. int found;
  3146.  
  3147.       if (!update_flag) {
  3148.          new_tail = xbuf->tail;
  3149.          new_segnum = xbuf->tail_segnum;
  3150.          found = FALSE;
  3151.          x = 0;
  3152.          if (old_segnum != new_segnum) {
  3153.             playtotal += xbuf->buf[old_segnum].Virt + xbuf->buf[old_segnum].length
  3154.                          - old_tail;
  3155.             if (++old_segnum >= num_xbuffers_p) {
  3156.                old_segnum = 0;
  3157.             } /* endif */
  3158.             while (old_segnum != new_segnum) {
  3159.                playtotal += xbuf->buf[old_segnum].length;
  3160.                if (++old_segnum >= num_xbuffers_p) {
  3161.                   old_segnum = 0;
  3162.                } /* endif */
  3163.             } /* endwhile */
  3164.             old_tail = xbuf->buf[old_segnum].Virt;
  3165.          } /* endif */
  3166.          if (old_tail < new_tail) {
  3167.             playtotal += new_tail - old_tail;
  3168.          } else if (old_tail > new_tail) {
  3169.             playtotal += xbuf->buf[old_segnum].length - (old_tail - new_tail);
  3170.          } /* endif */
  3171.          old_tail = new_tail;
  3172.  
  3173.          if (old_playtotal != playtotal) {
  3174.             old_playtotal = playtotal;
  3175.             if (!supress) {
  3176.                _settextposition(15,((short)(strlen(help_msg[PLAYING1][6]))+5));
  3177.                printf("%6.6ld",playtotal);
  3178.                if (pos_flag) {
  3179.                   _settextposition(11,((short)(strlen(extra_msg[POSITION]))+5));
  3180.                   printf("%6.6ld",xbuf->position);
  3181.                } /* endif */
  3182.             } /* endif */
  3183.          } /* endif */
  3184.       } /* endif */
  3185.  
  3186. } /* update_count */
  3187.  
  3188. /*****************************************************************************/
  3189. /*                                                                           */
  3190. /*      FUNCTION NAME = midi2seq                                             */
  3191. /*                                                                           */
  3192. /*      FUNCTION = Convert MIDI standard file to .SEQ format file            */
  3193. /*                                                                           */
  3194. /*      INPUT PARAMETERS = byte_count - length of chunk                      */
  3195. /*                                                                           */
  3196. /*      RETURN CODE = 0 Successful                                           */
  3197. /*                    1 Failure                                              */
  3198. /*                                                                           */
  3199. /*****************************************************************************/
  3200.  
  3201. int midi2seq(unsigned long byte_count)   /* Begin Function                   */
  3202. {
  3203.  
  3204. /*****************************************************************************/
  3205. /*                   LOCAL VARIABLE DEFINITIONS                              */
  3206. /*****************************************************************************/
  3207.  
  3208. char            keynums[16][16];       /* id of notes currently on           */
  3209. char            maxnotes[16];          /* max # notes for each chan          */
  3210. char            numnotes[16];          /* # notes current on                 */
  3211. char            totnumnotes;           /* total # of notes on                */
  3212. char            totmaxnotes;           /* total max # of notes ever on       */
  3213.  
  3214. FILE  *tmpstr = NULL;                  /* Temp file during merge             */
  3215.  
  3216. int   chan;                            /* Temporary MIDI channel var         */
  3217. int   cpqn;                            /* Clocks per quarter note            */
  3218. int   division;                        /* Division from header               */
  3219. int   smpte;                           /* SMPTE timing flag                  */
  3220. int   sysex;                           /* SysEx flag                         */
  3221. int   tempo;                           /* Current Tempo in bpm               */
  3222. unsigned int trk;                      /* Temp current trk num               */
  3223. int   x;                               /* Temporary variable                 */
  3224. int   key_hit;
  3225.  
  3226. unsigned int  maxtrack;                /* Current track number               */
  3227. unsigned char b3;                      /* temp MIDI byte 3                   */
  3228. unsigned char ch;                      /* temp MIDI byte read from inhndl    */
  3229. unsigned char tptr;                    /* temp char pointer                  */
  3230. unsigned char metatype;                /* Meta type id                       */
  3231. unsigned char mrunstat;                /* Master running status              */
  3232. unsigned char tsden;                   /* Time signature denominator         */
  3233. unsigned char tsmet;                   /* # clocks between met clicks        */
  3234. unsigned char tsnum;                   /* Time signature numerator           */
  3235. unsigned char ts32pq;                  /* # 1/32 notes per MIDI clock        */
  3236. unsigned char tbuf[4097];              /* Temp read buffer                   */
  3237.  
  3238.  
  3239. unsigned long len;                     /* Chunk length                       */
  3240. unsigned long len2;                    /* Event len                          */
  3241. unsigned long tlong;                   /* temp long var (for tempo)          */
  3242.  
  3243. unsigned int format;                   /* Format type from header            */
  3244. unsigned int ntracks;                  /* # tracks from header               */
  3245.  
  3246.  
  3247. unsigned int    progchgs[16];          /* # prog changes each channel        */
  3248. unsigned long   trksize[128];          /* Track size                         */
  3249.  
  3250. unsigned char   *trkbuffer[128];       /* ptr to start of buffer             */
  3251. unsigned char   runstat[128];          /* Current running status             */
  3252.  
  3253. /*****************************************************************************/
  3254.  
  3255.    /**************************************************************************/
  3256.    /* Initialize, and Set default values                                     */
  3257.    /**************************************************************************/
  3258.    midi_buff_index = 0;
  3259.    totnumnotes = 0;
  3260.    totmaxnotes = 0;
  3261.  
  3262.    /* Initialize the number of notes, max number of notes, and number of     */
  3263.    /* program changes to 0 for all channels.                                 */
  3264.    for ( chan=0; chan<16; chan++) {
  3265.  
  3266.       numnotes[chan] = 0;
  3267.       maxnotes[chan] = 0;
  3268.       progchgs[chan] = 0;
  3269.  
  3270.       /* initialize all notes to 'not on'                                    */
  3271.       for (x=0; x<16; x++) {
  3272.  
  3273.          keynums[chan][x] = -1;
  3274.  
  3275.       } /* end for x=0 to 16 */
  3276.  
  3277.    } /* end for chan=0 to 16 */
  3278.  
  3279.    tempo = 120;                        /* 000 Provide default tempo          */
  3280.    smpte = 0;                          /* 000 clear SMPTE flag               */
  3281.    cpqn = 96;                          /* 000 Provide default CPQN           */
  3282.    sysex = 0;                          /* 000 Clear SysEx flag               */
  3283.    maxtrack = 0;                       /* 000 count of tracks proc'd         */
  3284.  
  3285.    /**************************************************************************/
  3286.    /* Read each CHUNK, and process based on type                             */
  3287.    /* This while loop will read each chunk and save the track chunks in      */
  3288.    /* trkdata()                                                              */
  3289.    /**************************************************************************/
  3290.    key_hit = 0;
  3291.    while ((user_esc == FALSE)                 /* 000 Loop until key pressed  */
  3292.           && (byte_count > 0)                 /* 000 not at end of chunk     */
  3293.           && (read(inhndl,tbuf,8) == 8) ) {   /* 000 chunk type & len        */
  3294.  
  3295.       byte_count -= 8;                        /* Decrement count             */
  3296.                                               /* Determine length of chunk   */
  3297.       len = (tbuf[4]<<24)                     /* 000 high byte 1st           */
  3298.            +(tbuf[5]<<16)                     /* 000 2nd                     */
  3299.            +(tbuf[6]<<8)                      /* 000 3rd                     */
  3300.            +(tbuf[7]);                        /* 000 low byte last (4th)     */
  3301.  
  3302.       /***********************************************************************/
  3303.       /* HEADER CHUNK                                                        */
  3304.       /***********************************************************************/
  3305.       if ( !(strncmp(tbuf,"MThd",4) ) ) { /* 000 HEADER CHUNK                */
  3306.  
  3307.          if (len > 4095) {        /* 000 Is our buffer big enough?           */
  3308.  
  3309.             outemsg(ERROR,HDRTOOBIG); /*   No, error message                  */
  3310.             exit(8);              /* 000  and exit                           */
  3311.  
  3312.          } else { /* buffer OK */
  3313.  
  3314.                                   /* Read entire header chunk into tbuf      */
  3315.             if ( (unsigned long)read(inhndl,tbuf,(int)len) !=len ) {
  3316.  
  3317.                outemsg(ERROR,ERRHDRDATA); /*  error message                   */
  3318.                exit(8);           /* 000  and exit                           */
  3319.  
  3320.             } /* endif */
  3321.  
  3322.             byte_count -= len;    /* Decrement counter                       */
  3323.                                   /* Determine format type: 0, 1, or 2       */
  3324.             format = (tbuf[0]<<8) /* 000 Format type MSB                     */
  3325.                      +tbuf[1];    /* 000  and LSB                            */
  3326.  
  3327.                                    /* Determine # of tracks in file -        */
  3328.                                    /* format 0 = 1 track always              */
  3329.             ntracks = (tbuf[2]<<8) /* 000 # tracks MSB                       */
  3330.                       +tbuf[3];    /* 000  and LSB                           */
  3331.  
  3332.                                     /* Determine the meaning of delta times  */
  3333.             division = (tbuf[4]<<8) /* 000 Division MSB                      */
  3334.                        +tbuf[5];    /* 000  and LSB                          */
  3335.  
  3336.  
  3337.             if (division < 0) {     /* if bit 15 = 1, then SMPTE time        */
  3338.  
  3339.                                         /* Calculate number of counts per    */
  3340.                                         /* quarter note                      */
  3341.                smpte = 1;               /* 000  set SMPTE flag               */
  3342.                cpqn = -(division>>8);   /* 000  # frames/sec                 */
  3343.                cpqn *= division & 0xff; /* 000 * ticks/frame                 */
  3344.  
  3345.             } else { /* metrical time */
  3346.  
  3347.                cpqn = division;         /* 000                               */
  3348.  
  3349.             } /* endif SMPTE time */
  3350.  
  3351.             /* Write timing control SysEx                                    */
  3352.             timinit[7] = (unsigned char)((cpqn / 24)-1);
  3353.  
  3354.             key_hit=send_data(midi_buff,midi_buff_index,0); /* Send anything in buff */
  3355.             midi_buff_index = 0;
  3356.             key_hit=send_data(timinit,10,0);  /* Send data to the audio device */
  3357.  
  3358.          } /* endif len > 4095 */
  3359.  
  3360.       /***********************************************************************/
  3361.       /* TRACK CHUNK                                                         */
  3362.       /***********************************************************************/
  3363.       } else if ( !(strncmp(tbuf,"MTrk",4) ) ) { /* 000 track chunk          */
  3364.  
  3365.          /* Set up buffer for this tracks data                               */
  3366.          if ( !(trkbuffer[maxtrack]=(unsigned char *)malloc(( (int)len+1) )) ) {
  3367.  
  3368.             outemsg(ERROR,NOMEMORY); /* Display error message                 */
  3369.             exit(12);          /* 000  and exit rc=12                        */
  3370.  
  3371.          } /* endif invalid trkbuffer allocation */
  3372.  
  3373.                                      /* Set data -> to start                 */
  3374.          trkdata[maxtrack] = trkbuffer[maxtrack];
  3375.          trksize[maxtrack] = len; /* 000 Save length of track                */
  3376.          trklen[maxtrack]  = len; /* 000 remaining length                    */
  3377.  
  3378.          /* Read track data into track's buffer                              */
  3379.          if (read(inhndl,trkbuffer[maxtrack],(int)len) != (int)len) {
  3380.  
  3381.             outemsg(ERROR,ERRTRKDATA); /* Display error message               */
  3382.             exit(16);          /* 000  and exit rc=16                        */
  3383.  
  3384.          } /* endif can't read track data                                    */
  3385.  
  3386.          byte_count -= len;           /* Decrement counter                   */
  3387.  
  3388.          maxtrack++;
  3389.  
  3390.       } else { /* unknown chunk */
  3391.  
  3392.          outmsg(WARNING,UNCHUNK);
  3393.          lseek(inhndl,len,SEEK_CUR); /* 000 skip over it                      */
  3394.  
  3395.       } /* endif header chunk */
  3396.  
  3397.    } /* end while user_esc == FALSE */
  3398.  
  3399.    /**************************************************************************/
  3400.    /* Now process each track's data which is now in trkdata[]                */
  3401.    /**************************************************************************/
  3402.    for (trk=0; trk<maxtrack; trk++) { /* Initialize data                     */
  3403.       runstat[trk] = 0;               /* 000 Init. running status            */
  3404.  
  3405.       /* Preload delta's for all tracks                                      */
  3406.       delta[trk] = 0;                 /* Init. delta time                    */
  3407.  
  3408.                                       /* get delta value - which is of       */
  3409.                                       /* variable length                     */
  3410.       do {                            /* get all delta bytes                 */
  3411.  
  3412.          ch = *trkdata[trk]++;        /* Read next byte                      */
  3413.          trklen[trk]--;               /* Reduce remaining len                */
  3414.          delta[trk] = (delta[trk]<<7) /* Shift delta and                     */
  3415.                      +(ch & 0x7f);    /*  add next delta byte                */
  3416.  
  3417.       } while (ch & 0x80);            /* Until bit 7 is clear                */
  3418.  
  3419.    } /* end for trk=0 to maxtrack */
  3420.  
  3421.    mrunstat = 0;                    /* Clear master running status           */
  3422.    remtracks = maxtrack;            /* Set # of tracks to do                 */
  3423.  
  3424.                                     /* Do this for all tracks                */
  3425.    while (remtracks && (user_esc == FALSE)) { /* Continue until all gone     */
  3426.  
  3427.       len=0xffffffff;               /* Some ridiculously big #               */
  3428.  
  3429.       for (trk=0; trk<maxtrack; trk++) { /* Find the smallest delta          */
  3430.  
  3431.                                     /* Determine which track has the smallest*/
  3432.                                     /* delta and store in len                */
  3433.          if (delta[trk] < len) {    /* Is it the smallest delta?             */
  3434.             len = delta[trk];       /*   if so, save it                      */
  3435.          } /* endif smallest delta */
  3436.  
  3437.       } /* end for trk=0 to maxtrack         len now == smallest delta       */
  3438.  
  3439.       /* Write out timing info                                               */
  3440.       len2 = len;
  3441. num_of_f8s += len2;
  3442.       while (len2 > 0x3fff) {       /* Need multiple SysExs?                 */
  3443.  
  3444.          timesysex[5] = 0x7f;          /*  Yes, send max lsb                 */
  3445.          timesysex[6] = 0x7f;          /*       and msb                      */
  3446.          key_hit=send_data(midi_buff,midi_buff_index,0); /* Send anything in buff */
  3447.          midi_buff_index = 0;
  3448.          key_hit=send_data(timesysex,8,0); /* Write it                 */
  3449.          mrunstat = 0;                 /* Clear master run stat              */
  3450.          len2 -= 0x3fff;               /* reduce remaining count             */
  3451.  
  3452.       } /* end while len2 > 0x3ffff */
  3453.  
  3454.       if (len2 > 8) {               /* Need to use a SysEx?                  */
  3455.  
  3456.          timesysex[5] = (unsigned char)(len2 & 0x7f); /* Yes, set lsb        */
  3457.          timesysex[6] = (unsigned char)(len2 >> 7);   /*      and msb        */
  3458.          key_hit=send_data(midi_buff,midi_buff_index,0); /* Send anything in buff */
  3459.          midi_buff_index = 0;
  3460.          key_hit=send_data(timesysex,8,0);  /* Write it                */
  3461.          mrunstat = 0;                      /* Clear master run stat         */
  3462.  
  3463.       } else while(len2--) {                /* No, just write F8's           */
  3464.  
  3465.             ch = 0xf8;
  3466.             buff_data(ch);
  3467.  
  3468.       } /* end while len2-- */
  3469.                                              /* send out data in order of    */
  3470.                                              /* smallest delta track goes    */
  3471.                                              /* next                         */
  3472.       if (user_esc == FALSE) {
  3473.  
  3474.          for (trk=0; trk<maxtrack; trk++){      /* Now proc each ready trk   */
  3475.  
  3476.             if ( (delta[trk] < 0xffffffff)      /* Is this trk still valid   */
  3477.                   && ((delta[trk]-=len)==0)     /* Is it time to do it?      */
  3478.                   && (user_esc == FALSE))    {
  3479.  
  3480.                /* Now read in event                                          */
  3481.                ch = nextbyte(trk);  /* Go get next byte                      */
  3482.  
  3483.                /**************************************************************/
  3484.                /* SYSEX EVENT                                                */
  3485.                /**************************************************************/
  3486.                if (ch==0xf0 || ch==0xf7) { /*  SysEx Event                   */
  3487.  
  3488.                   runstat[trk] = 0;  /* Cancel running status because of     */
  3489.                                      /* system exclusive message             */
  3490.  
  3491.                   if (ch==0xf0) buff_data(ch);/*Write if F0 byte*/
  3492.  
  3493.                   /* Read in variable length event len                       */
  3494.                   len2 = 0;          /* Clear event len                      */
  3495.  
  3496.                   do {               /* get all len bytes                    */
  3497.  
  3498.                      ch = nextbyte(trk);     /* Read next byte               */
  3499.                      len2 = (len2<<7)        /* Shift delta and              */
  3500.                            +(ch & 0x7f);     /*  add next byte               */
  3501.  
  3502.                   } while (ch & 0x80);       /* Until bit 7 is 0             */
  3503.  
  3504.                   if (len2 < 4096){          /* Make sure there's room       */
  3505.                      key_hit=send_data(midi_buff,midi_buff_index,0); /* Send anything in buff */
  3506.                      midi_buff_index = 0;
  3507.                      key_hit=send_data(trkdata[trk],(long)len2,0);
  3508.                      trkdata[trk]+=len2;     /* Updata pointer               */
  3509.                      trklen[trk] -= len2;    /*  and rem len                 */
  3510.  
  3511.                   } else { /* no room */
  3512.  
  3513.                      outemsg(ERROR,NOMEMSYS);
  3514.                      trkdata[trk] += len2;
  3515.                      trklen[trk] -= len2;
  3516.  
  3517.                   } /* endif room */
  3518.  
  3519.                /**************************************************************/
  3520.                /* META EVENT                                                 */
  3521.                /**************************************************************/
  3522.                } else if (ch==0xff) {   /* Meta event ?                      */
  3523.  
  3524.                   metatype = nextbyte(trk); /* Get Meta Type                 */
  3525.  
  3526.                   runstat[trk] = 0;        /* Cancel running status          */
  3527.  
  3528.                   /* Read in variable length event len                       */
  3529.                   len2 = 0;                /* Clear event len                */
  3530.  
  3531.                   do {                     /* get all len bytes              */
  3532.  
  3533.                      ch = nextbyte(trk);   /* Read next byte                 */
  3534.                      len2 = (len2<<7)      /* Shift delta and                */
  3535.                            +(ch & 0x7f);   /*  add next byte                 */
  3536.  
  3537.                   } while (ch & 0x80);     /* Until bit 7 is 0               */
  3538.  
  3539.                   switch(metatype){        /* Process meta events            */
  3540.                      case 0x00:            /* Sequence Number                */
  3541.                      case 0x01:            /* Text                           */
  3542.                      case 0x02:            /* Copyright Notice               */
  3543.                      case 0x03:            /* Sequence/Track name            */
  3544.                      case 0x04:            /* Instrument Name                */
  3545.                      case 0x05:            /* Lyric                          */
  3546.                      case 0x06:            /* Marker                         */
  3547.                      case 0x07:            /* Cue Point                      */
  3548.                      case 0x20:            /* MIDI Channel Prefix            */
  3549.                      case 0x2f:            /* End of Track                   */
  3550.                           break;
  3551.  
  3552.                      case 0x51:                       /* Tempo               */
  3553.                           tlong = *trkdata[trk];      /* usecs per qtr note  */
  3554.                           tlong <<= 8;                /* shift left a byte   */
  3555.                           tlong += *(trkdata[trk]+1); /* get next            */
  3556.                           tlong <<= 8;                /* shift left 1 more byte*/
  3557.                           tlong += *(trkdata[trk]+2); /* get lsb             */
  3558.                           tempo = (int)(60000000/tlong);
  3559.                           tempo_sysex[6] = (unsigned char)((tempo*10) & 0x7f);
  3560.                           tempo_sysex[7] = (unsigned char)((tempo*10) >> 7);
  3561.                           key_hit=send_data(midi_buff,midi_buff_index,0); /* Send anything in buff */
  3562.                           midi_buff_index = 0;
  3563.                           key_hit=send_data(tempo_sysex,10,0);
  3564.                           break;
  3565.  
  3566.                      case 0x54:         /* SMPTE Offset                      */
  3567.                           break;
  3568.  
  3569.                      case 0x58:                      /* Time Signature       */
  3570.                           tsnum= *trkdata[trk];      /* numerator            */
  3571.                           tsden= *(trkdata[trk]+1);  /* denominator 2**-n    */
  3572.                           tsmet= *(trkdata[trk]+2);  /* # clocks/met click   */
  3573.                           ts32pq= *(trkdata[trk]+3); /* # 1/32 notes/MIDI clk*/
  3574.                           break;
  3575.  
  3576.                      case 0x59:         /* Key Signature                     */
  3577.                      case 0x7f:         /* Seq-specific event                */
  3578.                           break;
  3579.  
  3580.                   } /* end switch */
  3581.  
  3582.                   trklen[trk] -= len2;    /* Update rem len                  */
  3583.                   trkdata[trk]+=len2;
  3584.  
  3585.                } else { /* not META event, try MIDI event */
  3586.  
  3587.                   /**************************************************************/
  3588.                   /* Process Status Byte (if any)                               */
  3589.                   /**************************************************************/
  3590.                   if (ch & 0x80) { /* Status Byte? (bit 7==1)                */
  3591.  
  3592.                      /* Do we want to run status here?                          */
  3593.                      runstat[trk] = ch;        /* save running status        */
  3594.                      mrunstat = ch;            /*  and master                */
  3595.                      chan = ch & 0x0f;         /* Save channel #             */
  3596.                      buff_data(ch);            /* Write it                 */
  3597.                      ch = nextbyte(trk);       /* Get next data byte         */
  3598.  
  3599.                   } /* endif status byte */
  3600.  
  3601.                   /* We have to write status byte if we can't run            */
  3602.                   if ( (runstat[trk] != mrunstat)    /* Is status same?      */
  3603.                      || mrunstat==0) {               /*   or zero?           */
  3604.  
  3605.                      mrunstat = runstat[trk];        /* if not, update it    */
  3606.                      chan = mrunstat & 0x0f;         /* Save channel #       */
  3607.                      buff_data(mrunstat);            /* Write it           */
  3608.  
  3609.                   } /* endif status same */
  3610.  
  3611.                   /***********************************************************/
  3612.                   /* Process by status type                                     */
  3613.                   /***********************************************************/
  3614.  
  3615.                   switch (runstat[trk] & 0xf0) {        /* Handle by group   */
  3616.                      case 0x80:                         /* Note Off          */
  3617.                           buff_data(ch);
  3618.                           tptr = nextbyte(trk);
  3619.                           buff_data(tptr);              /*Write 3rd byte     */
  3620.  
  3621.                           /* Reduce count of total notes on                  */
  3622.                           if (--totnumnotes < 0) {
  3623.                              totnumnotes = 0;
  3624.                           } /* endif totnumnote < 0 */
  3625.  
  3626.                           /* Reduce count of # notes on                      */
  3627.                           if (--numnotes[chan] < 0) {
  3628.                              outmsg(WARNING,NOTES);
  3629.                              numnotes[chan] = 0;
  3630.                           } /* endif numnotes[chan] < 0 */
  3631.  
  3632.                           /* See of matching note-on                         */
  3633.                           for (x=0; x<16 && (keynums[chan][x]!=(char)ch); x++);
  3634.  
  3635.                           if (x<16) {
  3636.                              keynums[chan][x] = -1;
  3637.                           } /* endif x < 16 */
  3638.  
  3639.                           break;
  3640.  
  3641.                      case 0x90:                       /* Note On             */
  3642.                           buff_data(ch);
  3643.                           b3 = nextbyte(trk);         /* Get 3rd byte        */
  3644.                           buff_data(b3);              /* Write 3rd byte      */
  3645.  
  3646.                           if (b3==0) {                /* Note Off?           */
  3647.                              /* Reduce count of total notes on               */
  3648.                              if (--totnumnotes < 0) {
  3649.                                 totnumnotes = 0;
  3650.                              } /* endif totnumnotes < 0 */
  3651.  
  3652.                              /* Reduce count of # notes on                   */
  3653.                              if (--numnotes[chan] < 0) {
  3654.                                 outmsg(WARNING,NOTES);
  3655.                                 numnotes[chan] = 0;
  3656.                              } /* endif numnotes[chan] < 0 */
  3657.  
  3658.                              /* See of matching note-on                      */
  3659.                              for (x=0; x<16 && (keynums[chan][x]!=(char)ch); x++);
  3660.  
  3661.                              if (x<16) {
  3662.                                 keynums[chan][x] = -1;
  3663.                              } /* endif x < 16 */
  3664.  
  3665.                           } else { /* b <> 0 */
  3666.  
  3667.                              /* Increase count of total notes on             */
  3668.                              if (++totnumnotes > totmaxnotes) {
  3669.                                 /* Keep track of highest ever                   */
  3670.                                 totmaxnotes = totnumnotes;
  3671.                              } /* endif totnumnotes ? totmaxnotes               */
  3672.  
  3673.                              /* Increase count of # notes on                 */
  3674.                              if (++numnotes[chan] > maxnotes[chan]) {
  3675.                                 /* Keep track of highest ever                   */
  3676.                                 maxnotes[chan] = numnotes[chan];
  3677.                              } /* endif numnotes[chan] > maxnotes[chan]         */
  3678.  
  3679.                              /* Assign a spot for it in keynums[]            */
  3680.                              for (x=0; x<16 && keynums[chan][x] != -1; x++);
  3681.  
  3682.                              if (x<16) {
  3683.                                 keynums[chan][x] = ch;
  3684.                              } /* endif x < 16 */
  3685.  
  3686.                           } /* endif b==0 */
  3687.                           break;
  3688.  
  3689.                      case 0xa0:                        /* Aftertouch         */
  3690.                           buff_data(ch);               /* Write it     */
  3691.                           tptr = nextbyte(trk);
  3692.                           buff_data(tptr);             /* Write 3rd byte     */
  3693.                           break;
  3694.  
  3695.                      case 0xb0:                        /* Control Change     */
  3696.                           buff_data(ch);               /* Write it     */
  3697.                           tptr = nextbyte(trk);
  3698.                           buff_data(tptr);             /* Write 3rd byte     */
  3699.                           break;
  3700.  
  3701.                      case 0xc0:                        /* Program Change     */
  3702.                           buff_data(ch);               /* Write it     */
  3703.                           progchgs[chan]++;            /* Keep count         */
  3704.                           break;
  3705.  
  3706.                      case 0xd0:                        /* Channel pressure   */
  3707.                           buff_data(ch);               /* Write it     */
  3708.                           break;
  3709.  
  3710.                      case 0xe0:                        /* Pitch bend         */
  3711.                           buff_data(ch);               /* Write it     */
  3712.                           tptr = nextbyte(trk);
  3713.                           buff_data(tptr);             /* Write 3rd byte     */
  3714.                           break;
  3715.  
  3716.                      case 0xf0:                        /* System             */
  3717.                           switch(runstat[trk]){
  3718.                              case 0xf0:                /* System Exclusive   */
  3719.                                   break;               /* (done above)       */
  3720.  
  3721.                              case 0xf1:                /* MTC Qtr Frame      */
  3722.                                   buff_data(ch);       /* Write it    */
  3723.                                   break;
  3724.  
  3725.                              case 0xf2:                      /* SPP          */
  3726.                                   buff_data(ch);             /* Write it     */
  3727.                                   tptr = nextbyte(trk);
  3728.                                   buff_data(tptr);          /* Write 3rd byte*/
  3729.                                   break;
  3730.  
  3731.                              case 0xf3:                       /* Song Select */
  3732.                              case 0xf4:                       /* n/a         */
  3733.                              case 0xf5:                       /* n/a         */
  3734.                              case 0xf6:                       /* Tune Request*/
  3735.                              case 0xf7:                       /* EOX         */
  3736.                              case 0xf8:                       /* Timing Clock*/
  3737.                              case 0xf9:                       /* n/a         */
  3738.                              case 0xfa:                       /* Start       */
  3739.                              case 0xfb:                       /* Continue    */
  3740.                              case 0xfc:                       /* Stop        */
  3741.                              case 0xfd:                       /* n/a         */
  3742.                              case 0xfe:                     /* Active Sensing*/
  3743.                              case 0xff:                       /* System Reset*/
  3744.                                   buff_data(ch);              /* Write it    */
  3745.                                   break;
  3746.  
  3747.                           } /* end switch runstat[trk] */
  3748.  
  3749.                      default:                               /* None          */
  3750.                           break;
  3751.  
  3752.                   } /* end switch runstat[trk] & 0xf0 */
  3753.  
  3754.                } /* endif SYSEX event */
  3755.  
  3756.                /* Reload delta time for this track                              */
  3757.                if (trklen[trk] > 0) {               /* Any more data ?       */
  3758.  
  3759.                   delta[trk] = 0;                   /* Clear delta time      */
  3760.  
  3761.                   do {                              /* get all delta bytes   */
  3762.                      ch = nextbyte(trk);            /* Read next byte        */
  3763.                      delta[trk] = (delta[trk]<<7)   /* Shift delta and       */
  3764.                                  +(ch & 0x7f);      /* add next delta byte   */
  3765.                   } while (ch & 0x80);              /* Until bit 7 is clear  */
  3766.  
  3767.                } /* endif trklen[trk] > 0 */
  3768.  
  3769.             } /* endif track still valid */
  3770.  
  3771.          } /* end for track=0 to maxtrack */
  3772.  
  3773.       } /* endif user_esc == FALSE */
  3774.  
  3775.    } /* end while (remtracks & user_esc == FALSE) */
  3776.  
  3777.    if (!user_esc) {
  3778.       send_data(midi_buff,midi_buff_index,0);
  3779.       if (audiowait) {
  3780.          #if IS_DOS
  3781.           if(rc = ioctl(0,AUDIO_WAIT,audhndl)){
  3782.          #else
  3783.           if(rc = DosDevIOCtl(0, NULL, 0x40+AUDIO_WAIT, 0x80, audhndl)) {
  3784.          #endif
  3785.             outmsg(ERROR,WAITIOCTL);      /* Write failed return code             */
  3786.             _settextposition(11,30);
  3787.             printf("%i",rc);
  3788.             endemsg(ERROR);
  3789.             close(audhndl);
  3790.             close(inhndl);
  3791.             freebuffs(xbuf->num_buffers,rbuf->num_buffers);
  3792.             return(1);
  3793.          }
  3794.          update_count();
  3795.          /* loop until get ESC character */
  3796.          while(!user_esc) {
  3797.            if (kbhit()) {
  3798.               key_hit = getch();
  3799.               if (key_hit == ESC) user_esc = TRUE;
  3800.            }
  3801.          }
  3802.       } else {
  3803.          while (!user_esc) {
  3804.             key_hit=send_data(&ch,0,0);    /* Waste time for music to finish*/
  3805.             if ((xbuf->count <= 0) && (old_playtotal != playtotal)) {
  3806.                old_playtotal = playtotal;
  3807.                strcpy(status,"Finished");
  3808.                _settextposition(12,((short)(strlen(help_msg[PLAYING1][3]))+5));
  3809.                printf("%s",status);
  3810.                if (batch) user_esc = TRUE;
  3811.                if (!supress && (old_runtotal != runtotal)) {
  3812.                   old_runtotal = runtotal;
  3813.                   _settextposition(16,((short)(strlen(help_msg[PLAYING1][7]))+5));
  3814.                   printf("%6.6ld",runtotal);
  3815.                   if (pos_flag) {
  3816.                      _settextposition(11,((short)(strlen(extra_msg[POSITION]))+5));
  3817.                      printf("%6.6ld",xbuf->position);
  3818.                   } /* endif */
  3819.                } /* endif */
  3820.                if (!batch) {
  3821.                   while(!user_esc) {
  3822.                      if (kbhit()) {
  3823.                         key_hit = getch();
  3824.                         if (key_hit == ESC) user_esc = TRUE;
  3825.                      }
  3826.                   }
  3827.                } /* endif */
  3828.             } else if ((xbuf->count <= 0) && (batch)) user_esc = TRUE;
  3829.  
  3830.          } /* end_while */
  3831.       } /* endif audiowait */
  3832.    } /* endif */
  3833.  
  3834.    for (remtracks=0; remtracks<maxtrack; remtracks++) {
  3835.       if(trkbuffer[remtracks]) free(trkbuffer[remtracks]);
  3836.    } /* endfor */
  3837.    return(0);
  3838.  
  3839. } /* end midi2seq */
  3840.  
  3841. /*****************************************************************************/
  3842. /*                                                                           */
  3843. /*      FUNCTION NAME = freebuffs                                            */
  3844. /*                                                                           */
  3845. /*      FUNCTION = Free all allocated buffers.                               */
  3846. /*                                                                           */
  3847. /*      INPUT PARAMETERS = xnum - number of xbuf buffers to free             */
  3848. /*                         rnum - number of rbuf buffers to free             */
  3849. /*                                                                           */
  3850. /*      RETURN CODE = none                                                   */
  3851. /*                                                                           */
  3852. /*****************************************************************************/
  3853.  
  3854. void freebuffs(unsigned int xnum, unsigned int rnum)
  3855. {
  3856.    unsigned int num;
  3857.  
  3858.    if (update_flag) {
  3859.       if (function == PLAY_DEMO) {
  3860.          num = xnum;
  3861.          for (sy = 0; sy<rnum; sy++) {
  3862.             if(rbuf->buf[sy].Virt) {
  3863.                _ffree(rbuf->buf[sy].Virt);
  3864.                rbuf->buf[sy].Virt = 0;
  3865.             } /* endif */
  3866.          } /* endfor */
  3867.       } else {
  3868.          num = rnum;
  3869.          for (sy = 0; sy<xnum; sy++) {
  3870.             if(xbuf->buf[sy].Virt) {
  3871.                _ffree(xbuf->buf[sy].Virt);
  3872.                xbuf->buf[sy].Virt = 0;
  3873.             } /* endif */
  3874.          } /* endfor */
  3875.       } /* endif */
  3876.       for (sy = 0; sy<num; sy++) {
  3877.          if(update_array[sy].Virt) {
  3878.             _ffree(update_array[sy].Virt);
  3879.             update_array[sy].Virt = 0;
  3880.          } /* endif */
  3881.       } /* endfor */
  3882.    } else {
  3883.       for (sy = 0; sy<rnum; sy++) {
  3884.          if(rbuf->buf[sy].Virt) {
  3885.             _ffree(rbuf->buf[sy].Virt);
  3886.             rbuf->buf[sy].Virt = 0;
  3887.          } /* endif */
  3888.       } /* endfor */
  3889.       for (sy = 0; sy<xnum; sy++) {
  3890.          if(xbuf->buf[sy].Virt) {
  3891.             _ffree(xbuf->buf[sy].Virt);
  3892.             xbuf->buf[sy].Virt = 0;
  3893.          } /* endif */
  3894.       } /* endfor */
  3895.    } /* endif */
  3896. } /* end freebuffs */
  3897.  
  3898. /*****************************************************************************/
  3899. /*                                                                           */
  3900. /*      FUNCTION NAME = nextbyte                                             */
  3901. /*                                                                           */
  3902. /*      FUNCTION = Retrieve next byte from track array accounting for end    */
  3903. /*                 of data.                                                  */
  3904. /*                                                                           */
  3905. /*      INPUT PARAMETERS = track - array of MIDI track chunk data.           */
  3906. /*                                                                           */
  3907. /*      RETURN CODE = ch - character read from array                         */
  3908. /*                                                                           */
  3909. /*****************************************************************************/
  3910.  
  3911. unsigned char nextbyte(track)
  3912. int     track;
  3913. {
  3914.    unsigned char ch;
  3915.  
  3916.    ch = *trkdata[track]++;
  3917.  
  3918.    if (--trklen[track] == 0) {         /* End of track                       */
  3919.  
  3920.       delta[track] = 0xffffffff;       /* Set max delta time                 */
  3921.       remtracks--;
  3922.  
  3923.    } /* endif trklen = 0 */
  3924.  
  3925.    return(ch);
  3926.  
  3927. } /* end nextbyte */
  3928.  
  3929. /*****************************************************************************/
  3930. /*                                                                           */
  3931. /*      FUNCTION NAME = buff_data                                            */
  3932. /*                                                                           */
  3933. /*      FUNCTION = Used to fill up intermediate buffer for midi2seq so       */
  3934. /*                 send_data not called for every byte.                     */
  3935. /*                 Will only send data when >50 bytes in the buffer.         */
  3936. /*                                                                           */
  3937. /*                                                                           */
  3938. /*      INPUT PARAMETERS = character to be added                             */
  3939. /*                                                                           */
  3940. /*      RETURN CODE = none                                                   */
  3941. /*                                                                           */
  3942. /*****************************************************************************/
  3943.  
  3944. void buff_data(unsigned char ch)
  3945. {
  3946.  
  3947.    midi_buff[midi_buff_index++] = ch;
  3948.    if (midi_buff_index >= MIDI_BUFF_LEN) {
  3949.       send_data(midi_buff,midi_buff_index,0);  /* Send data to the audio device */
  3950.       midi_buff_index = 0;
  3951.    } /* endif */
  3952.  
  3953. } /* end buff_data */
  3954.  
  3955. /*****************************************************************************/
  3956. /*                                                                           */
  3957. /*      FUNCTION NAME = seq2midi                                             */
  3958. /*                                                                           */
  3959. /*      FUNCTION = Convert Audio DD output data to MIDI standard file.       */
  3960. /*                                                                           */
  3961. /*      INPUT PARAMETERS = buffer - pointer to input data buffer to be xlated*/
  3962. /*                         count - length of data in buffer                  */
  3963. /*                         f8_count_ptr - ptr to variable with current # of  */
  3964. /*                                        F8 timing bytes from previous      */
  3965. /*                                        buffers to be added to sysex msg   */
  3966. /*                                                                           */
  3967. /*      RETURN CODE = 0 Successful                                           */
  3968. /*                    1 Failure                                              */
  3969. /*                                                                           */
  3970. /*****************************************************************************/
  3971.  
  3972. int seq2midi(unsigned char *buffer, int count, unsigned long *f8_count_ptr)
  3973. {
  3974.  
  3975. unsigned char   conv_buf[512];
  3976. unsigned char   ch;
  3977.  
  3978. unsigned long   temp_val,          /* used in writing variable length data   */
  3979.                 value;             /* used in writing variable length data   */
  3980.  
  3981. int             j,                 /* index into conv_buff                   */
  3982.                 i,
  3983.                 ndata;
  3984. char            flag;              /* flag to break out of loop              */
  3985.  
  3986. /*****************************************************************************/
  3987. /*                   LOCAL VARIABLE DEFINITIONS                              */
  3988. /*****************************************************************************/
  3989.  
  3990.    i = 0;                                /* init index into buffer           */
  3991.    j = 0;                                /* init index into converted buffer */
  3992.  
  3993.  
  3994.    do {
  3995.       /***********************************************************************/
  3996.       /* Check next byte - if new status then process it, else if same old   */
  3997.       /* status eat this byte. if not a status byte just put in buffer.      */
  3998.       /***********************************************************************/
  3999.       if ((ch=buffer[i]) & 0x80) {            /* check to see if status byte */
  4000.  
  4001.          switch (ch & 0xF0) {
  4002.             case NOTE_OFF:
  4003.             case NOTE_ON:
  4004.             case KEY_PRESSURE:
  4005.             case CONTROL_CHANGE:
  4006.             case PITCH_BEND:
  4007.                  data_bytes++;                /* Need a total of 2 data bytes*/
  4008.                                               /* get the other one below     */
  4009.             case PROGRAM_CHANGE:
  4010.             case CHANNEL_PRESSURE:
  4011.                  data_bytes++;                /* Need a total of 1 data byte */
  4012.  
  4013.                  last_data_bytes = data_bytes;      /* remember total # of   */
  4014.                                                     /* data bytes expected   */
  4015.                                                     /* for this status       */
  4016.                  if (*f8_count_ptr > 0) {
  4017.                     value = *f8_count_ptr;          /* get any F8's from prev*/
  4018.                                                     /* buffer(s)             */
  4019.  
  4020.                     *f8_count_ptr = 0;              /* set back to zero now  */
  4021.                                                     /* that these have been  */
  4022.                                                     /* counted               */
  4023.                     temp_val = value & 0x7F;
  4024.  
  4025.                     while (( value >>= 7) > 0) {
  4026.                        temp_val <<= 8;
  4027.                        temp_val |= 0x80;
  4028.                        temp_val += (value & 0x7F);
  4029.                     } /* end while */
  4030.  
  4031.                     /* put delay time into conv_buf                          */
  4032.                     flag = TRUE;
  4033.  
  4034.                     while (flag) {
  4035.                        conv_buf[j++] = (unsigned char)(temp_val & 0xFF);
  4036.                        if (temp_val & 0x80) {
  4037.                           temp_val >>= 8;
  4038.                        } else {
  4039.                           flag = FALSE;
  4040.                        } /* end if */
  4041.  
  4042.                     } /* end while */
  4043.  
  4044.                  } else { /* no previous F8's */
  4045.  
  4046.                     if (!delta_time) {
  4047.                        conv_buf[j++] = 0;        /* Put in delta time of 0   */
  4048.                     } /* endif */
  4049.  
  4050.                  } /* endif */
  4051.  
  4052.                  delta_time = TRUE;
  4053.  
  4054.                  if (running_status != ch) {
  4055.  
  4056.                     conv_buf[j++] = ch;          /* put status in output     */
  4057.                     running_status = ch;         /* update running status    */
  4058.  
  4059.                     delta_time = FALSE;
  4060.  
  4061.                  } /* endif running status != ch */
  4062.  
  4063.                  i++;                            /* go to next character     */
  4064.  
  4065.                  break;
  4066.  
  4067.             /* No system exclusive messages (F0) should be seen coming       */
  4068.             /* from the device driver. The rest of the system messages       */
  4069.             /* F1-FF may be seen but should not be placed in the MIDI        */
  4070.             /* file and should be "eaten" with the exception of the          */
  4071.             /* TIMING_CLOCK which should be translated into a delta_time     */
  4072.             /* variable length value.                                        */
  4073.  
  4074.             default:
  4075.  
  4076.                  switch (ch) {
  4077.  
  4078.                     case TIMING_CLOCK:
  4079.                          /* determine how many ticks                        */
  4080.                          value = 1;
  4081.                          while ((++i < count) && (buffer[i] == TIMING_CLOCK))
  4082.                             value++;
  4083.  
  4084.                          if ((data_bytes <= 0) &&
  4085.                              (i < count)) {  /* did F8's run off end of buf?*/
  4086.                                              /* NO                          */
  4087.                             value += *f8_count_ptr;/* add any F8's from prev*/
  4088.                                                    /* buffer(s)             */
  4089.  
  4090.                             *f8_count_ptr = 0;     /* set back to zero now  */
  4091.                                                    /* that these have been  */
  4092.                                                    /* counted               */
  4093.                             temp_val = value & 0x7F;
  4094.  
  4095.                             while (( value >>= 7) > 0) {
  4096.                                temp_val <<= 8;
  4097.                                temp_val |= 0x80;
  4098.                                temp_val += (value & 0x7F);
  4099.                             } /* end while */
  4100.  
  4101.                             /* put delay time into conv_buf                 */
  4102.                             flag = TRUE;
  4103.  
  4104.                             while (flag) {
  4105.                                conv_buf[j++] = (unsigned char)(temp_val & 0xFF);
  4106.  
  4107.                                if (temp_val & 0x80) {
  4108.                                   temp_val >>= 8;
  4109.                                } else {
  4110.                                   flag = FALSE;
  4111.                                } /* end if */
  4112.  
  4113.                             } /* end while */
  4114.  
  4115.                             delta_time = TRUE;
  4116.  
  4117.                          } else {                  /* whole message not here */
  4118.  
  4119.                             *f8_count_ptr += value;
  4120.  
  4121.                          } /* endif */
  4122.                          break;
  4123.  
  4124.                     case MTC_QUARTER_FRAME:
  4125.                     case SELECT_SONG:
  4126.                          eat = 1;         /* be sure and eat the next data  */
  4127.                          i++;             /* byte that comes through        */
  4128.                          break;
  4129.  
  4130.                     case SONG_POSITION:
  4131.                          eat = 2;         /* be sure and eat the next 2 data*/
  4132.                          i++;             /* bytes that come through        */
  4133.                          break;
  4134.  
  4135.                     case 0xF0:
  4136.                          while (buffer[i++] != 0xF7); /* eat all bytes until EOX*/
  4137.                          break;
  4138.  
  4139.                     case TUNE_REQUEST:
  4140.                     case EOX:
  4141.                     case START:
  4142.                     case CONT:
  4143.                     case STOP:
  4144.                     case ACTIVE_SENSING:
  4145.                     case SYSTEM_RESET:
  4146.                     default:
  4147.                          i++;           /* eat this byte and continue       */
  4148.                         break;
  4149.                  } /* end switch (ch) */
  4150.                  break;
  4151.  
  4152.          } /* end switch (ch & 0xF0) */
  4153.  
  4154.       } else { /* not a status byte - must be data byte */
  4155.  
  4156.          if (data_bytes == 0) {
  4157.                                     /* this byte was not expected which means*/
  4158.                                     /* that no status was given (running     */
  4159.                                     /* status to be used and F8's should be  */
  4160.                                     /* handled now                           */
  4161.             if (*f8_count_ptr > 0) {
  4162.                value = *f8_count_ptr;               /* get any F8's from prev*/
  4163.                                                     /* buffer(s)             */
  4164.  
  4165.                *f8_count_ptr = 0;                   /* set back to zero now  */
  4166.                                                     /* that these have been  */
  4167.                                                     /* counted               */
  4168.                temp_val = value & 0x7F;
  4169.  
  4170.                while (( value >>= 7) > 0) {
  4171.                   temp_val <<= 8;
  4172.                   temp_val |= 0x80;
  4173.                   temp_val += (value & 0x7F);
  4174.                } /* end while */
  4175.  
  4176.                /* put delay time into conv_buf                               */
  4177.                flag = TRUE;
  4178.  
  4179.                while (flag) {
  4180.                   conv_buf[j++] = (unsigned char)(temp_val & 0xFF);
  4181.  
  4182.                   if (temp_val & 0x80) {
  4183.                      temp_val >>= 8;
  4184.                   } else {
  4185.                      flag = FALSE;
  4186.                   } /* end if */
  4187.  
  4188.                } /* end while */
  4189.  
  4190.             } else { /* no F8's - means a delta time of 0 or F8's just       */
  4191.                      /* written out                                          */
  4192.                if (!delta_time) {
  4193.                   conv_buf[j++] = 0;               /* put in 0 delta time    */
  4194.                } /* endif */
  4195.  
  4196.             } /* endif */
  4197.  
  4198.             delta_time = TRUE;
  4199.             data_bytes = last_data_bytes;   /* init # of bytes for this      */
  4200.                                             /* running status                */
  4201.          } /* endif data_bytes = 0 */
  4202.  
  4203.          data_bytes--;                      /* subtract this data byte       */
  4204.  
  4205.          if (eat) {
  4206.             eat--;
  4207.          } else { /* don't eat it */
  4208.             conv_buf[j++] = ch;             /* put in convert buffer         */
  4209.             delta_time = FALSE;             /* just wrote in data - so       */
  4210.                                             /* delta_time no longer last     */
  4211.                                             /* thing written                 */
  4212.          } /* end if (eat */
  4213.  
  4214.          i++;
  4215.  
  4216.       } /* endif */
  4217.  
  4218.    } while ( (i < count) && (!kbhit()) ); /* enddo */
  4219.  
  4220.    if (j > 0) {
  4221.  
  4222.       /* Write out the buffer */
  4223.       ndata = (unsigned)write(inhndl,(char *)conv_buf,j);
  4224.       if(ndata==65535){
  4225.  
  4226.         outmsg(HELP,CLEARSCRN);
  4227.         outmsg(ERROR,DISKFULL);
  4228.         _settextposition(10,30);
  4229.         printf("%s", iname);
  4230.         endemsg(ERROR);
  4231.         return (1);
  4232.  
  4233.       } /* endif fwrite */
  4234.  
  4235.    } /* endif */
  4236.  
  4237.  
  4238.    return((int)i);
  4239.  
  4240. } /* end seq2midi */
  4241.  
  4242. /*****************************************************************************/
  4243. /*                                                                           */
  4244. /*      FUNCTION NAME = dcwrite                                              */
  4245. /*                                                                           */
  4246. /*      FUNCTION = Direct buffer write.                                      */
  4247. /*                                                                           */
  4248. /*      INPUT PARAMETERS = data - data to be written to buffer               */
  4249. /*                         len - amount of data to be written                */
  4250. /*                                                                           */
  4251. /*      RETURN CODE = none                                                   */
  4252. /*                                                                           */
  4253. /*****************************************************************************/
  4254.  
  4255. void dcwrite(data,len,num_buffers)
  4256. char *data;
  4257. int len;
  4258. unsigned int num_buffers;
  4259. {
  4260.  
  4261.    while(len--){
  4262.  
  4263.       while(xbuf->count == xbuf->size);       /* Wait until there's room       */
  4264.  
  4265.          *xbuf->head = *data++;              /* Copy a byte                   */
  4266.          xbuf->runflags |= IOBUF_LOCK;
  4267.          ++xbuf->count;
  4268.          xbuf->runflags &= ~IOBUF_LOCK;
  4269.           /* Time to wrap ptr?    */
  4270.          if(++xbuf->head >= xbuf->buf[xbuf->head_segnum].Virt+xbuf->buf[xbuf->head_segnum].length){
  4271.             if (++xbuf->head_segnum >= num_buffers) {
  4272.                xbuf->head_segnum = 0;
  4273.             } /* endif */
  4274.             xbuf->head = xbuf->buf[xbuf->head_segnum].Virt;
  4275.          } /* end if */
  4276.  
  4277.    } /* end while */
  4278.  
  4279. }
  4280.  
  4281. #if IS_DOS
  4282. /*****************************************************************************/
  4283. /*                                                                           */
  4284. /*      FUNCTION NAME = ioctl                                                */
  4285. /*                                                                           */
  4286. /*      FUNCTION = Issue DOS IOCTL.                                          */
  4287. /*                                                                           */
  4288. /*      INPUT PARAMETERS = Data - pointer to data structure for IOCTL        */
  4289. /*                         Function - IOCTL funtion                          */
  4290. /*                         DevHandle - Audio device handle                   */
  4291. /*                                                                           */
  4292. /*      RETURN CODE = none                                                   */
  4293. /*                                                                           */
  4294. /*****************************************************************************/
  4295. int   ioctl(Data,Function,DevHandle)
  4296. void far *Data;
  4297. unsigned char Function;
  4298. int DevHandle;
  4299. {
  4300.    int   rc;
  4301. #if 0
  4302.    _asm{
  4303.       push  ds
  4304.       mov   ax,440ch
  4305.       mov   bx,DevHandle
  4306.       mov   cl,Function
  4307.       add   cl,40h
  4308.       mov   ch,0x80        ; Category
  4309.       lds   dx,Data
  4310.       int   21h
  4311.       pop   ds
  4312.       jc    error
  4313.       mov   ax,0
  4314.    error:
  4315.       mov   rc,ax
  4316.    }
  4317. #else
  4318.    union REGS dosregs;
  4319.    struct SREGS segregs;
  4320.  
  4321.    dosregs.x.ax=0x440c;
  4322.    dosregs.x.bx=DevHandle;
  4323.    dosregs.h.cl=(char)(Function+0x40);
  4324.    dosregs.h.ch=0x80;
  4325.    dosregs.x.dx=FP_OFF(Data);
  4326.    segregs.ds=FP_SEG(Data);
  4327.    intdosx(&dosregs,&dosregs,&segregs);
  4328.    if(dosregs.x.cflag==0) rc=0;
  4329.    else rc=dosregs.x.ax;
  4330. #endif
  4331.    return(rc);
  4332. }
  4333.  
  4334. /*****************************************************************************/
  4335. /*                                                                           */
  4336. /*      FUNCTION NAME = dspload                                              */
  4337. /*                                                                           */
  4338. /*      FUNCTION = Load module onto DSP (DOS version)                        */
  4339. /*                                                                           */
  4340. /*      INPUT PARAMETERS = name - DSP module name to be loaded               */
  4341. /*                         audstr - name of audio device                     */
  4342. /*                                                                           */
  4343. /*      RETURN CODE = 0 - successful                                         */
  4344. /*                   -1 - failed                                             */
  4345. /*                                                                           */
  4346. /*****************************************************************************/
  4347. int dspload(name,audstr)
  4348. char *name;
  4349. int audstr;
  4350. {
  4351.    FILE *str;
  4352.    struct audio_load load;
  4353.    unsigned long sz;
  4354.    char *buf;
  4355.  
  4356.    audstr = audstr;                /* For compiler warning - also to make call*/
  4357.                                    /* compatible with OS/2 call               */
  4358.    if(!(str=fopen(name,"rb"))){
  4359.       outmsg(ERROR,DSPOPEN);
  4360.       _settextposition(11,30);
  4361.       printf("%s",name);
  4362.       endemsg(ERROR);
  4363.       return(-1);
  4364.    }
  4365.    fseek(str,-1,SEEK_END);         /* Determine size       */
  4366.    sz = ftell(str)+1;
  4367.    if(!(buf = malloc((size_t)sz))){
  4368.       outemsg(ERROR,NOMEMDSP);
  4369.       if(buf) free(buf);
  4370.       fclose(str);
  4371.       return(-1);
  4372.    }
  4373.    fseek(str,0,SEEK_SET);          /* Seek to beginning    */
  4374.    fread(buf,1,(int)sz,str);
  4375.    fclose(str);
  4376.  
  4377.    load.buffer = buf;               /* Issue load IOCTL     */
  4378.    load.size = sz;
  4379.    load.flags = LOAD_START | LOAD_END;
  4380.    if(direct_call == NULL){
  4381.       ioctl(&load,AUDIO_LOAD,audhndl);
  4382.    }else{
  4383.       (*direct_call)(EP_LOAD,(char far *)&load,23);
  4384.    }
  4385.  
  4386.  
  4387.    if(buf) free(buf);
  4388.    return(0);
  4389.  
  4390. } /* end dspload for DOS */
  4391.  
  4392. #else    /* OS/2 mode DSPLOAD module */
  4393.  
  4394. /*****************************************************************************/
  4395. /*                                                                           */
  4396. /*      FUNCTION NAME = dspload                                              */
  4397. /*                                                                           */
  4398. /*      FUNCTION = Load module onto DSP (OS/2 version)                       */
  4399. /*                                                                           */
  4400. /*      INPUT PARAMETERS = name - DSP module name to be loaded               */
  4401. /*                         audstr - name of audio device                     */
  4402. /*                                                                           */
  4403. /*      RETURN CODE = 0 - successful                                         */
  4404. /*                   -1 - failed                                             */
  4405. /*                                                                           */
  4406. /*****************************************************************************/
  4407. int dspload(name,audstr)
  4408. char *name;
  4409. HFILE audstr;
  4410. {
  4411.    FILE *str;
  4412.    struct audio_load load;
  4413.    char buf[256];
  4414.  
  4415.    if(!(str=fopen(name,"rb"))){
  4416.       outmsg(ERROR,DSPOPEN);
  4417.       _settextposition(11,30);
  4418.       printf("%s",name);
  4419.       endemsg(ERROR);
  4420.       return(-1);
  4421.    }
  4422.    load.buffer = buf;                                 /* Issue load IOCTL     */
  4423.    load.flags = LOAD_START;
  4424.    do{
  4425.       load.size = fread(buf,1,256,str);
  4426.       if(load.size != 256) load.flags |= LOAD_END;             /* Last block  */
  4427.       if(DosDevIOCtl(&load, NULL, 0x40+AUDIO_LOAD, 0x80, audstr) != 0) { /* load it  */
  4428.          outemsg(ERROR,EAUDIOLOAD);
  4429.          fclose(str);
  4430.          return(-1);
  4431.       }
  4432.       load.flags = 0;
  4433.    }while(load.size == 256);
  4434.    fclose(str);
  4435.    return(0);
  4436.  
  4437. } /* end DSPLOAD for OS/2 mode */
  4438.  
  4439. #endif
  4440.  
  4441. /*****************************************************************************/
  4442. /*                                                                           */
  4443. /*      FUNCTION NAME = change_settings                                      */
  4444. /*                                                                           */
  4445. /*      FUNCTION = Change the Volume/Balance setting                         */
  4446. /*                                                                           */
  4447. /*      INPUT PARAMETERS = none                                              */
  4448. /*                                                                           */
  4449. /*      RETURN CODE = none                                                   */
  4450. /*                                                                           */
  4451. /*****************************************************************************/
  4452. void change_settings()
  4453. {
  4454.    #if IS_OS2
  4455.     int   rc;
  4456.    #endif
  4457.    struct   audio_control control;
  4458.    struct   audio_change change;
  4459.  
  4460.    _settextposition(13,((short)(strlen(help_msg[PLAYING1][4]))+5));
  4461.    printf("%s",cur_volume_s);
  4462.    _settextposition(14,((short)(strlen(help_msg[PLAYING1][5]))+5));
  4463.    printf("%s",cur_balance_s);
  4464.  
  4465.    /* Issue CHANGE IOCtl */
  4466.    control.position = 0;                     /* Do it now                  */
  4467.    control.ioctl_request = AUDIO_CHANGE;     /* Change configuration       */
  4468.    control.return_code = 0;                  /* zero out return code field */
  4469.    control.request_info = &change;           /* Request data = change struct*/
  4470.  
  4471.    change.input_list[0].devtype = cur_input;
  4472.    change.input_list[0].devnum  = DEVICE_1;
  4473.    change.output_list[0].devtype = source_output;
  4474.    change.output_list[0].devnum  = DEVICE_1;
  4475.    change.input_list[1].devtype = NULL_INPUT;
  4476.    change.input_list[1].devnum  = DEVICE_1;
  4477.    change.output_list[1].devtype = NULL_OUTPUT;
  4478.    change.output_list[1].devnum  = DEVICE_1;
  4479.    change.input = INPUTS_LISTED;
  4480.    change.output = OUTPUTS_LISTED;           /* Output select              */
  4481.    change.monitor = monitor;                 /* Monitor not applicable     */
  4482.    change.volume = cur_volume;               /* Volume set to maximum      */
  4483.    change.volume_delay = delay;              /* Set volume across 5 seconds*/
  4484.    change.balance = cur_balance;             /* Balance set to mid-point   */
  4485.    change.balance_delay = delay;             /* Set balance in 5 seconds   */
  4486.    change.treble = 0x3fffffff;               /* Mid point                  */
  4487.    change.bass = 0x3fffffff;                 /* Mid point                  */
  4488.    change.pitch = 0;                         /*                            */
  4489.    if (mastervol) {
  4490.    change.dev_info = &devinfo;               /* Device dependent data      */
  4491.    } else {
  4492.    change.dev_info = NULL;                   /* No device dependent data   */
  4493.    }
  4494.    change.input_gain = 0;                    /* No input gain              */
  4495.    change.mode_info = NULL;                  /* No mode dependent data     */
  4496.    #if IS_OS2
  4497.     if((rc = DosDevIOCtl(&control, NULL, 0x40+AUDIO_CONTROL, 0x80, audhndl)) ||
  4498.        (control.return_code == 12)) {
  4499.       outmsg(ERROR,ECHNGIOCTL);
  4500.       _settextposition(11,30);
  4501.       printf("%i %i",rc,control.return_code);
  4502.       endemsg(ERROR);
  4503.       close(audhndl);
  4504.       close(inhndl);
  4505.     } /* endif rc = audio_ioctl */
  4506.    #else
  4507.     if(direct_call == NULL){
  4508.       ioctl(&control,AUDIO_CONTROL,audhndl);
  4509.     }else{
  4510.       (*direct_call)(EP_CONTROL,(char far *)&control,23);
  4511.     }
  4512.    #endif
  4513.  
  4514. } /* end change_settings */
  4515.  
  4516. /*****************************************************************************/
  4517. /*                                                                           */
  4518. /*      FUNCTION NAME = outemsg                                              */
  4519. /*                                                                           */
  4520. /*      FUNCTION = Output error message to display and call endemsg.         */
  4521. /*                                                                           */
  4522. /*      INPUT PARAMETERS = type - type of message to be output               */
  4523. /*                         msg_num - message number                          */
  4524. /*                                                                           */
  4525. /*      RETURN CODE = none                                                   */
  4526. /*                                                                           */
  4527. /*****************************************************************************/
  4528. void outemsg(type,msg_num)
  4529. int     type;
  4530. int     msg_num;
  4531.  
  4532. {
  4533.    outmsg(type,msg_num);
  4534.    endemsg(type);
  4535.  
  4536. } /* end outemsg */
  4537.  
  4538. /*****************************************************************************/
  4539. /*                                                                           */
  4540. /*      FUNCTION NAME = endemsg                                              */
  4541. /*                                                                           */
  4542. /*      FUNCTION = Output status message to the display                      */
  4543. /*                 and then wait for key to be hit and then clear            */
  4544. /*                 the screen.                                               */
  4545. /*                                                                           */
  4546. /*      INPUT PARAMETERS = type - type of message to be output               */
  4547. /*                                                                           */
  4548. /*      RETURN CODE = none                                                   */
  4549. /*                                                                           */
  4550. /*****************************************************************************/
  4551. void endemsg(type)
  4552.  
  4553. int     type;
  4554.  
  4555. {
  4556.    outmsg(STATUS,CONTINUE);
  4557.    getch();
  4558.    outmsg(type,CLEARSCRN);
  4559.    outmsg(STATUS,CLEARSCRN);
  4560. } /* endemsg */
  4561.  
  4562. /*****************************************************************************/
  4563. /*                                                                           */
  4564. /*      FUNCTION NAME = outmsg                                               */
  4565. /*                                                                           */
  4566. /*      FUNCTION = Output a message to the display.                          */
  4567. /*                                                                           */
  4568. /*      INPUT PARAMETERS = type - type of message to be output               */
  4569. /*                         msg_num - message number                          */
  4570. /*                                                                           */
  4571. /*      RETURN CODE = none                                                   */
  4572. /*                                                                           */
  4573. /*****************************************************************************/
  4574. void outmsg(type, msg_num)
  4575. int     type;
  4576. int     msg_num;
  4577.  
  4578. {
  4579.  
  4580.    switch(type) {
  4581.  
  4582.       case STATUS:
  4583.            _settextposition(21,5);
  4584.            if (msg_num == CLEARSCRN) {
  4585.               _setbkcolor(BLUE);          /* Set background color            */
  4586.               _settextcolor(BLUE);        /* Set foreground/text color       */
  4587.               _outtext(BLANK_70);         /* Display the status message      */
  4588.            } else { /* a real message to put out */
  4589.               _setbkcolor(GREEN);         /* Set background color            */
  4590.               _settextcolor(BLACK);       /* Set foreground/text color       */
  4591.               _outtext(status_msg[msg_num][0]); /* Disp the status message   */
  4592.            } /* endif msg_num = CLRSCRN */
  4593.            break;
  4594.  
  4595.       case VBHELP:
  4596.            _settextposition(22,5);
  4597.            if (msg_num == CLEARSCRN) {
  4598.               _setbkcolor(BLUE);          /* Set background color            */
  4599.               _settextcolor(BLUE);        /* Set foreground/text color       */
  4600.               _outtext(BLANK_70);         /* Clear the status message        */
  4601.            } else { /* a real message to put out */
  4602.               _setbkcolor(GREEN);         /* Set background color            */
  4603.               _settextcolor(BLACK);       /* Set foreground/text color       */
  4604.               _outtext(vbhelp_msg[msg_num][0]); /* Disp the vol/bal message  */
  4605.            } /* endif msg_num = CLRSCRN */
  4606.            break;
  4607.  
  4608.       case USERINPUT:
  4609.            if (msg_num == CLEARSCRN) {
  4610.               _setbkcolor(BLUE);          /* Set background color            */
  4611.               _settextcolor(BLUE);        /* Set foreground/text color       */
  4612.               _settextposition(5,5);
  4613.               _outtext(BLANK_70);
  4614.               _settextposition(6,5);
  4615.               _outtext(BLANK_70);
  4616.               _settextposition(7,5);
  4617.               _outtext(BLANK_70);
  4618.            } else { /* a real message to put out */
  4619.               _setbkcolor(BLUE);          /* Set background color            */
  4620.               _settextcolor(WHITE);       /* Set foreground/text color       */
  4621.                                           /* Display the user input message  */
  4622.               _settextposition(5,5);
  4623.               _outtext(user_msg[msg_num][0]);
  4624.               _settextposition(6,5);
  4625.               _outtext(user_msg[msg_num][1]);
  4626.               _settextposition(7,5);
  4627.               _outtext(BLANK_70);
  4628.            } /* endif msg_num = CLRSCRN */
  4629.            break;
  4630.  
  4631.       case ERROR:
  4632.            if (msg_num == CLEARSCRN) {
  4633.               _setbkcolor(BLUE);          /* Set background color            */
  4634.               _settextcolor(BLUE);        /* Set foreground/text color       */
  4635.               _settextposition(9,5);
  4636.               _outtext(BLANK_70);
  4637.               _settextposition(10,5);
  4638.               _outtext(BLANK_70);
  4639.               _settextposition(11,5);
  4640.               _outtext(BLANK_70);
  4641.               _settextposition(12,5);
  4642.               _outtext(BLANK_70);
  4643.            } else { /* a real message to put out */
  4644.               _setbkcolor(RED);           /* Set background color               */
  4645.               _settextcolor(BLACK);       /* Set foreground/text color          */
  4646.                                           /* Display the error message       */
  4647.               _settextposition(9,5);
  4648.               _outtext(error_msg[msg_num][0]);
  4649.               _settextposition(10,5);
  4650.               _outtext(error_msg[msg_num][1]);
  4651.               _settextposition(11,5);
  4652.               _outtext(error_msg[msg_num][2]);
  4653.               _settextposition(12,5);
  4654.               _outtext(error_msg[msg_num][3]);
  4655.            } /* endif msg_num = CLRSCRN */
  4656.            break;
  4657.  
  4658.       case WARNING:
  4659.            if ((msg_num == CLEARSCRN) || (msg_num == BLANK)) {
  4660.               if (msg_num == CLEARSCRN) {
  4661.                  _setbkcolor(BLUE);       /* Set background color            */
  4662.                  _settextcolor(BLUE);     /* Set foreground/text color       */
  4663.               } else { /* BLANK */
  4664.                  _setbkcolor(GRAY);       /* Set background color            */
  4665.                  _settextcolor(RED);      /* Set foreground/text color       */
  4666.               } /* endif */
  4667.               _settextposition(18,5);
  4668.               _outtext(BLANK_70);
  4669.               _settextposition(19,5);
  4670.               _outtext(BLANK_70);
  4671.               _settextposition(20,5);
  4672.               _outtext(BLANK_70);
  4673.            } else { /* a real message to put out */
  4674.               _setbkcolor(GRAY);          /* Set background color            */
  4675.               _settextcolor(RED);         /* Set foreground/text color       */
  4676.                                           /* Display the warning message     */
  4677.               _settextposition(18,5);
  4678.               _outtext(warning_msg[msg_num][0]);
  4679.               _settextposition(19,5);
  4680.               _outtext(warning_msg[msg_num][1]);
  4681.               _settextposition(20,5);
  4682.               _outtext(warning_msg[msg_num][2]);
  4683.            } /* endif msg_num = CLRSCRN */
  4684.            break;
  4685.  
  4686.       case HELP:
  4687.            if ((msg_num == CLEARSCRN) || (msg_num == BLANK)) {
  4688.               if (msg_num == CLEARSCRN) {
  4689.                  _setbkcolor(BLUE);       /* Set background color            */
  4690.                  _settextcolor(BLUE);     /* Set foreground/text color       */
  4691.               } else { /* BLANK */
  4692.                  _setbkcolor(AQUA);       /* Set background color            */
  4693.                  _settextcolor(BLACK);    /* Set foreground/text color       */
  4694.               } /* endif */
  4695.               _settextposition(9,5);
  4696.               _outtext(BLANK_70);
  4697.               _settextposition(10,5);
  4698.               _outtext(BLANK_70);
  4699.               _settextposition(11,5);
  4700.               _outtext(BLANK_70);
  4701.               _settextposition(12,5);
  4702.               _outtext(BLANK_70);
  4703.               _settextposition(13,5);
  4704.               _outtext(BLANK_70);
  4705.               _settextposition(14,5);
  4706.               _outtext(BLANK_70);
  4707.               _settextposition(15,5);
  4708.               _outtext(BLANK_70);
  4709.               _settextposition(16,5);
  4710.               _outtext(BLANK_70);
  4711.               _settextposition(17,5);
  4712.               _outtext(BLANK_70);
  4713.            } else { /* a real message to put out */
  4714.               _setbkcolor(AQUA);          /* Set background color            */
  4715.               _settextcolor(BLACK);       /* Set foreground/text color       */
  4716.                                           /* Display the help message        */
  4717.               _settextposition(9,5);
  4718.               _outtext(help_msg[msg_num][0]);
  4719.               _settextposition(10,5);
  4720.               _outtext(help_msg[msg_num][1]);
  4721.               _settextposition(11,5);
  4722.               _outtext(help_msg[msg_num][2]);
  4723.               _settextposition(12,5);
  4724.               _outtext(help_msg[msg_num][3]);
  4725.               _settextposition(13,5);
  4726.               _outtext(help_msg[msg_num][4]);
  4727.               _settextposition(14,5);
  4728.               _outtext(help_msg[msg_num][5]);
  4729.               _settextposition(15,5);
  4730.               _outtext(help_msg[msg_num][6]);
  4731.               _settextposition(16,5);
  4732.               _outtext(help_msg[msg_num][7]);
  4733.               _settextposition(17,5);
  4734.               _outtext(help_msg[msg_num][8]);
  4735.            } /* endif msg_num = CLRSCRN */
  4736.            break;
  4737.  
  4738.       case YNQUEST:
  4739.            _settextposition(8,5);
  4740.            if (msg_num == CLEARSCRN) {
  4741.               _setbkcolor(BLUE);              /* Set background color        */
  4742.               _settextcolor(BLUE);            /* Set foreground/text color   */
  4743.               _outtext(BLANK_70);             /* Display the Y/N question    */
  4744.            } else { /* a real message to put out */
  4745.               _setbkcolor(BLUE);              /* Set background color        */
  4746.               _settextcolor(WHITE);           /* Set foreground/text color   */
  4747.               _outtext(ynquest_msg[msg_num][0]); /* Disp the Y/N question    */
  4748.            } /* endif msg_num = CLRSCRN */
  4749.            break;
  4750.  
  4751.       case TITLE:
  4752.            if (msg_num == CLEARSCRN) {
  4753.               _setbkcolor(BLUE);              /* Set background color        */
  4754.               _settextcolor(BLUE);            /* Set foreground/text color   */
  4755.               _settextposition(2,1);
  4756.               _outtext(BLANK_70);
  4757.               _settextposition(3,1);
  4758.               _outtext(BLANK_70);
  4759.            } else { /* a real message to put out */
  4760.               _setbkcolor(BLUE);          /* Set background color            */
  4761.               _settextcolor(WHITE);       /* Set foreground/text color       */
  4762.                                           /* Display the title message       */
  4763.               _settextposition(2,1);
  4764.               _outtext(title_msg[msg_num][0]);
  4765.               _settextposition(3,1);
  4766.               _outtext(title_msg[msg_num][1]);
  4767.            } /* endif msg_num = CLRSCRN */
  4768.            break;
  4769.  
  4770.       case COPYRIGHT:
  4771.            _setbkcolor(BLUE);          /* Set background color               */
  4772.            _settextcolor(WHITE);       /* Set foreground/text color          */
  4773.            _settextposition(24,1);     /* Write out copyright msg to display */
  4774.            _outtext(copyright_msg[msg_num][0]);
  4775.            break;
  4776.  
  4777.       case CLHELP:
  4778.            _setbkcolor(BLUE);          /* Set background color            */
  4779.            _settextcolor(WHITE);       /* Set foreground/text color       */
  4780.                                           /* Display the title message       */
  4781.            _settextposition(3,1);
  4782.            _outtext(clhelp_msg[msg_num][0]);
  4783.            _settextposition(4,1);
  4784.            _outtext(clhelp_msg[msg_num][1]);
  4785.            _settextposition(5,1);
  4786.            _outtext(clhelp_msg[msg_num][2]);
  4787.            _settextposition(6,1);
  4788.            _outtext(clhelp_msg[msg_num][3]);
  4789.            _settextposition(7,1);
  4790.            _outtext(clhelp_msg[msg_num][4]);
  4791.            _settextposition(8,1);
  4792.            _outtext(clhelp_msg[msg_num][5]);
  4793.            _settextposition(9,1);
  4794.            _outtext(clhelp_msg[msg_num][6]);
  4795.            _settextposition(10,1);
  4796.            _outtext(clhelp_msg[msg_num][7]);
  4797.            _settextposition(11,1);
  4798.            _outtext(clhelp_msg[msg_num][8]);
  4799.            _settextposition(12,1);
  4800.            _outtext(clhelp_msg[msg_num][9]);
  4801.            _settextposition(13,1);
  4802.            _outtext(clhelp_msg[msg_num][10]);
  4803.            _settextposition(14,1);
  4804.            _outtext(clhelp_msg[msg_num][11]);
  4805.            _settextposition(15,1);
  4806.            _outtext(clhelp_msg[msg_num][12]);
  4807.            _settextposition(16,1);
  4808.            _outtext(clhelp_msg[msg_num][13]);
  4809.            _settextposition(17,1);
  4810.            _outtext(clhelp_msg[msg_num][14]);
  4811.            _settextposition(18,1);
  4812.            _outtext(clhelp_msg[msg_num][15]);
  4813.            _settextposition(19,1);
  4814.            _outtext(clhelp_msg[msg_num][16]);
  4815.            _settextposition(20,1);
  4816.            _outtext(clhelp_msg[msg_num][17]);
  4817.            _settextposition(21,1);
  4818.            _outtext(clhelp_msg[msg_num][18]);
  4819.            _settextposition(22,1);
  4820.            break;
  4821.  
  4822.    } /* end switch (type) */
  4823.  
  4824. } /* end outmsg */
  4825.  
  4826. /*****************************************************************************/
  4827. /*                                                                           */
  4828. /*      FUNCTION NAME = read_kb                                              */
  4829. /*                                                                           */
  4830. /*      FUNCTION = Read a character from stream input                        */
  4831. /*                                                                           */
  4832. /*      INPUT PARAMETERS = string_read - ptr to string to be read            */
  4833. /*                         length      - max length of string                */
  4834. /*                                                                           */
  4835. /*      RETURN CODE = character read                                         */
  4836. /*                                                                           */
  4837. /*****************************************************************************/
  4838. int read_kb(char *string_read,unsigned int length)
  4839. {
  4840.    unsigned int x;
  4841.    int ch;
  4842.    unsigned int string_len;
  4843.    int finished;
  4844.  
  4845.    for (x=0; x<length; x++) {
  4846.       string_read[x] = '\0';
  4847.    } /* end for */
  4848.  
  4849.    finished = FALSE;
  4850.  
  4851.    while (!(finished)) {
  4852.  
  4853.       ch = getch();
  4854.       switch(ch) {
  4855.          case ENTER10:
  4856.          case ENTER13:
  4857.               finished = TRUE;
  4858.               break;
  4859.          case ESC:
  4860.               return(1);
  4861.               break;
  4862.          case SPACE:
  4863.               break;
  4864.          case BACKSPACE:
  4865.               if (string_len = strlen(string_read)) {
  4866.                  putch(BACKSPACE);
  4867.                  putch(SPACE);
  4868.                  putch(BACKSPACE);
  4869.                  string_read[string_len-1] = '\0';
  4870.               } /* endif */
  4871.               break;
  4872.            case UP_ARROW:
  4873.                  string_len = strlen(old_string_read);
  4874.                  for (x=0; x<string_len; x++) {
  4875.                     putch(old_string_read[x]);
  4876.                     strcat(string_read,(char *)&old_string_read[x]);
  4877.                  } /* endfor */
  4878.               break;
  4879.          default:
  4880.               if (strlen(string_read) <= (length-1)) {
  4881.                  putch(ch);
  4882.                  strcat(string_read,(char *)&ch);
  4883.               } /* endif */
  4884.       } /* switch */
  4885.  
  4886.    } /* endwhile */
  4887.  
  4888.    for (x=0; x<length; x++) {
  4889.       old_string_read[x] = '\0';
  4890.    } /* end for */
  4891.    string_len = strlen(string_read);
  4892.    for (x=0; x<string_len; x++) {
  4893.       strcat(old_string_read,(char *)&string_read[x]);
  4894.    } /* endfor */
  4895.  
  4896.    return(0);
  4897.  
  4898. } /* end read_kb */
  4899.  
  4900.